1

自从Android引入了库项目以来,我一直在将我的应用程序转换为库,以便可以通过适当的调整来制作多个版本(例如,使用相同的自由和专业版本代码库,但改变了一些东西)。从Android库调用非库代码

我最初有麻烦让图书馆项目的代码访问我的子项目中的字段。换句话说,我的免费和专业版本每个都有一个包含少量常量的类,图书馆项目将用它来区分某些功能。

在子项目中,我扩展了库的主要活动并添加了一个静态初始化块,它使用反射更改库中字段的值。

public class MyMainActivityProVersion extends MyMainActivity { 

    public static final String TAG = Constants.APP_NAME + "/SubClass"; 

    static { 
     try { 
      ConstantsHelper.setConstants(Constants.class); 
     } catch (Exception e) { 
      Log.d(TAG, "--- Constants not initialised! ---"); 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
    } 
} 

在这段代码,ConstantsHelper是在图书馆,和我从我的子项目提供Constants.class。这会初始化库项目中的常量。

我的方法很好,除了一个特定的用例。当应用程序在一段时间内没有被使用并且被操作系统“停止”时,ConstantsHelper中的静态字段将被遗忘。

常数应该由主要活动重置(如上所示),但主要活动甚至没有启动,因为操作系统恢复了不同的活动。其结果是,常量的初始化被遗忘了,我不能重新初始化它们,因为恢复的活动在图书馆(它不知道子项目)。

我该如何'告诉'库中的其他活动来调用子项目中的代码来恢复?或者,是否有办法确保我的子项目中的某些代码在每个简历上都被调用?

+0

我可能可以解释类加载器中发生的事情,但我还没有完全理解 - 您是指“图书馆中恢复的活动”是什么意思?它是'MyMainActivityProVersion',正确的,它在你的应用程序中。常数被遗忘是什么意思? –

+0

MyMainActivity继续调用一些其他活动,在这种情况下它是ViewerActivity,它驻留在库项目中。如果用户在ViewerActivity上,然后按下“home”,应用程序最终会关闭,并且ConstantsHelper中的常量必须重新初始化。他们不重新初始化,因为当用户恢复应用程序时,恢复的活动是ViewerActivity,并且我上面的重要代码没有执行 – HXCaine

+0

因此,常量值不仅仅是ProVersionActivity?你知道应用程序类吗?无论启动的“子活动”如何,它都会创建一次。 – thaussma

回答

0

恐怕我从来没有找到这个问题的好答案。我可能会继续使用可怕的反射,并找出一些黑客的解决方法。

我觉得我应该回来,至少指出我没有解决这个问题,为了这个页面的其他人的利益。

0

我认为你是通过尝试通过静态成员在两个活动间共享数据来“作弊”的。当他们在相同的或相关的类加载器中时,这恰好工作。在这里我相信Android使用单独的类加载器来执行单独的活动,但是,子活动位于子类加载器中。所以ViewActivity恰好能够看到父类加载器并查看父类的静态。后来我相信父母会离开,所以当你下次访问时,你的孩子在本地重新加载MyMainActivity,并且它没有按照你的意愿初始化。 (好吧,如果不是这样的话,这是非常像这样的解释。)

我认为还有一些更强大的选择。您可以使用LicenseChecker API来决定您是否使用免费或付费版本,而不是依赖活动生命周期和类加载器的详细信息。这可能会更好,因为它可以保护您免受其他类型的未经授权的使用。

+0

您可能误解了情况(并且我不'不要怪你,阅读文字说明很难)。我不是在活动中共享静态成员,而是通过图书馆中的常量类来共享这些静态成员,并通过子项目的活动“填充”有用的信息。所有图书馆的活动都可以访问它。但是,当应用程序被操作系统杀死时,常量类是“未初始化”的,我无法让库项目“查看”子项目及其中的代码来填充这些项目常量。这是我的问题 – HXCaine

+0

我可能会误解,但是你所描述的仍然听起来像你依赖与类本身相关的东西,而不是对象或实例。一个类不能“uninitialize” - 但是你肯定可以在一个新的类加载器中重新加载这个类,或者发现自己创建一个新的单例类或者什么东西,这是我给出的原因。它仍然可能是一个红鲱鱼 - 将不得不看代码 - 但希望澄清这个想法是否相关。 –

0

您可以使用Android资源解决此问题。 基本上,在库项目的资源xml值文件中定义常量
E.g. “lib项目”\ values \常量。XML

<resources xmlns:tools="http://schemas.android.com/tools"> 
    <bool name="const_free_version">false</bool> 
    <string name="const_a_constant">pippo</bool> 
</resources> 

然后,在你的子项目,你可以使用不同的资源XML值文件重新定义的lib项目值:
例如“子项目” \值\ constants.xml

<resources xmlns:tools="http://schemas.android.com/tools"> 
    <bool name="const_free_version">true</bool> 
</resources> 

在你的lib项目代码时,你指的R.bool.const_free_version你基于子项目常量XML的实际值。
请注意,您不必重新定义lib项目constants.xml中定义的每个值,但只需要在子项目中使用不同的值。

相关问题