从Android库调用非库代码

时间:2011-09-25 10:52:30

标签: android reflection android-library static-initialization

由于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。这会初始化库项目中的常量。

除了一个特定的用例外,我的方法很有效。当应用程序暂时没有被使用并且被OS“停止”时,ConstantsHelper中的静态字段将被遗忘。

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

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

3 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

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

我觉得我应该回来,至少指出我没有解决这个问题,以便其他人来到这个页面。

答案 2 :(得分:0)

您可以使用Android资源解决此问题。 基本上,在Library项目的资源xml值文件中定义常量
例如。 " lib项目" \ 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值:
例如。 &#34;子项目&#34; \ values \ constants.xml

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

在引用R.bool.const_free_version的lib项目代码中,您可以根据子项目常量值xml获得实际值。
请注意,您不必重新定义lib项目constants.xml中定义的每个值,而只需要重新定义子项目中需要的值。

相关问题