1

自从 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 中的静态字段会被遗忘。

常量应该由主要活动重置(如上所示),但主要活动甚至没有启动,因为操作系统恢复了不同的活动。这样做的结果是常量的初始化被忘记了,我无法重新初始化它们,因为恢复的活动在库中(它不知道子项目)。

如何“告诉”库中的其他活动在恢复时从子项目中调用代码?或者,有没有办法确保我的子项目中的某些代码在每份简历上都被调用?

4

3 回答 3

0

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

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

于 2011-09-25T11:52:30.570 回答
0

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

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

于 2011-10-31T10:42:02.527 回答
0

您可以使用 Android 资源解决此问题。基本上,在您的库项目中的资源 xml 值文件中定义您的常量,
例如“lib project”\values\constants.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-project 值:
例如“子项目”\values\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 中定义的每个值,而只需重新定义子项目中需要的不同值。

于 2015-06-25T07:38:02.560 回答