1

在 Android 上编写这样的兼容代码是否安全?

if (Build.os.SDK_INT >= 11) {
    newClass instance = new newClass();
    ....
}
else {
    oldClass instance = new oldClass();
    ....
}

我的一位同事与我争辩说,在运行上述代码时可能会抛出 ClassNotFoundException,因为 ClassLoader 试图在低于 android 11 的 android os 设备上加载 newClass。但我尝试了几次,但没有看到这个发生。在谷歌搜索了几个小时后,我没有找到任何关于 android 默认 classLoader 如何以及何时加载特定类的信息。

4

4 回答 4

0

你总是可以reflection用来检查类是否存在:

try {
  Class.forName("yourclass")
} catch (ClassNotFoundExecption) {
  oldClass instance = new oldClass();
}
于 2012-10-13T09:27:09.160 回答
0

你应该像下面这样检查兼容性......它比上面的更准确:

   private static int currentApi = 0;

   public static int getApiLevel() {

    if (currentApi > 0) {
        return currentApi;
    }

    if (android.os.Build.VERSION.SDK.equalsIgnoreCase("3")) {
        currentApi = 3;
    } else {
        try {
            Field f = android.os.Build.VERSION.class.getDeclaredField("SDK_INT");
            currentApi = (Integer) f.get(null);
        } catch (Exception e) {
            return 0;
        }
    }

    return currentApi;
}
于 2012-10-13T09:10:28.660 回答
0

是的,这在最新版本的 Android 上是安全的。我想说 froyo 及以上,但它可能比这更早。我不记得了。

发生的情况是 dalvik 在安装时对 dex 文件执行验证通过。对于它无法解析的任何类/方法/字段,它会将这些访问替换为引发验证错误的指令。

在您的示例中,如果加载了该代码,例如 api 10,则newClass instance = new newClass()在概念上将替换为throw new VerifYError(). 因此,只要该分支永远不会在运行时执行,一切都很好。

于 2012-10-13T17:36:11.657 回答
-1

简短的回答 - 不要这样做。

大多数虚拟机只在绝对需要时才加载一个类。但是,允许类加载器预先缓存类的二进制表示[1]。

允许类加载器缓存类型的二进制表示,在预期最终使用的早期加载类型,或在相关组中一起加载类型。

[1] - http://www.artima.com/insidejvm/ed2/lifetype2.html

[2] - http://developer.android.com/tools/extras/support-library.html

编辑 - 您是否检查过您需要的类是否作为 android 支持包的一部分提供?[2]

于 2012-10-13T09:15:41.897 回答