【问题标题】:Dynamic class loading to target multiple Android versions针对多个 Android 版本的动态类加载
【发布时间】:2011-04-01 15:18:05
【问题描述】:

我想为多个 Android 版本(可能每个版本)制作一个 Android 应用 我的问题是我想检查应用程序当前运行的 Android 版本是什么,并动态加载一个依赖于版本的类。这部分应该没问题。

我只是想知道如何在我的 Eclipse 项目中没有编译错误的情况下实现这一点。 我的意思是,该项目是为特定目标(1.5、2.1 ...)配置的,因此如果我的项目中的某个类与所选目标不兼容,则会导致错误。

有没有办法导出这些类,即使它们不适合平台(我想过一个单独的库,但又一次:如何在没有编译 pbs 的情况下将这些类编译成一个库?)?这应该没问题,因为在我检查 Android 版本后要求他们加载之前,它们不会被加载。

谢谢!

【问题讨论】:

    标签: android classloader multitargeting


    【解决方案1】:

    如果您使用最新目标编译项目,即 2.2,它仍将在 1.5 上运行。

    【讨论】:

    • 这根本不是真的。 2.2 中有许多方法(特别是在电话包中),但 1.5 中没有。相反的可能是正确的,但是您将无法使用新功能。
    • 好吧,我没有说您可以使用任何 2.2 功能并在 1.5 上运行。我说你可以用 2.2 编译 1.5 兼容的代码,它会在 1.5 上运行。这家伙想写这样一个真正可行的代码。
    • 好吧,我只是不想做出向后兼容性的假设,我的意思是,想象一下 1.5 中已弃用的字段最终在 2.2 中删除?如果我在 2.2 中构建我的项目,我猜我看不到它。我的目标是每个版本都 100% 兼容。但我并不是说您的解决方案在 1.5 和 2.2 之间不起作用......但可能在 1.0 和 3.0+ 之间......但是谢谢!
    【解决方案2】:

    您可以使用Class.forName 根据不同的条件加载不同的类:

    public interface MyType {}
    public class MyTypeOn15 implements MyType {}
    public class MyTypeOn16 implements MyType {}
    public class MyTypeOn20 implements MyType {}
    // ...
    

    以及代码中的其他地方:

    MyType myType = null;
    if (getActualTarget().equals("1.5") {
       myType = Class.forName("MyTypeOn15").newInstance();
    } else if (getActualTarget().equals("1.6") {
       myType = Class.forName("MyTypeOn16").newInstance();
    } // ...
    

    请注意,您的实现中需要一个可访问的空构造函数。而getActualTarget() 是您的魔术方法,它将目标作为字符串标识符返回...

    【讨论】:

    • 感谢您的回复!用魔术方法,你的意思是它不存在,我必须自己写? :) 这就是我试图通过访问 android.os.Build.VERSION_CODES 来做的事情,但这在 1.5 中不存在......所以我需要一种方法来检查旧版本的平台版本(也许缺少这个字段可以是一个标准吗?)。我希望这种神奇的方法存在:)。但是我的问题是,由于我选择了不兼容的 Android 目标,您如何在我的项目中拥有 MyTypeOn15.java 文件而不会出现编译错误?谢谢
    • 哦,这没什么大不了的。创建目标和类匹配的单独项目,当您创建可部署时,只需将所有这些类复制到一个库中。然后库包含不会在实际环境中运行的类,但这无关紧要,因为它们没有被使用和加载。
    • 啊,好吧,我正在考虑类似的事情,但我希望我能用一个项目来完成它^^。但我还不知道如何为 Android 项目 (:s) 创建一个库。我可以只“jar”我的几个平台特定项目的 .class 文件并将这个 jar 添加到 Eclipse 的 buildPath->libraries 中以用于我的“一体化”项目吗?我试试这个,好像解决了我的问题,谢谢!
    • 我得到一个 ClassNotFoundException: Class> clazz = Class.forName("fully.qualified.name.MyTypeOn16"); MyTypeOn16 已放入一个 jar 中,该 jar 已添加到项目类路径中。与android有什么特别的关系吗?也许得到一个类加载器?
    • 不,抱歉,我在构建 jar 文件时犯了一个错误。再次感谢,它有效;)
    猜你喜欢
    • 2010-12-14
    • 1970-01-01
    • 1970-01-01
    • 2011-03-20
    • 1970-01-01
    • 2011-08-13
    • 2011-06-17
    • 2015-06-30
    • 1970-01-01
    相关资源
    最近更新 更多