Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/202.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
这样写Android兼容代码安全吗?_Android_Dalvik - Fatal编程技术网

这样写Android兼容代码安全吗?

这样写Android兼容代码安全吗?,android,dalvik,Android,Dalvik,在Android上编写这样的兼容代码安全吗 if (Build.os.SDK_INT >= 11) { newClass instance = new newClass(); .... } else { oldClass instance = new oldClass(); .... } 我的一位同事与我争辩说,运行上述代码时可能会抛出ClassNotFoundException,因为ClassLoader试图在低于android 11的android操作

在Android上编写这样的兼容代码安全吗

if (Build.os.SDK_INT >= 11) {
    newClass instance = new newClass();
    ....
}
else {
    oldClass instance = new oldClass();
    ....
}
我的一位同事与我争辩说,运行上述代码时可能会抛出ClassNotFoundException,因为ClassLoader试图在低于android 11的android操作系统设备上加载newClass。但我试过好几次,都没看到这种情况发生。
在谷歌搜索了几个小时后,我没有找到任何关于android默认类加载器如何以及何时加载特定类的信息

您应该检查兼容性,如下所示。。。它比上述内容更准确:

   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;
}

简短的回答-不要这样做

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

类装入器可以缓存类型的二进制表示形式, 预期最终使用的早期荷载类型,或荷载类型 在相关的小组里一起

[1] -

[2] -


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

您始终可以使用
反射检查类是否存在:

try {
  Class.forName("yourclass")
} catch (ClassNotFoundExecption) {
  oldClass instance = new oldClass();
}

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

发生的情况是dalvik在安装时对dex文件执行验证传递。对于无法解析的任何类/方法/字段,它将用抛出VerifyError的指令替换这些访问


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

当然,在Android上使用反射是可行的。然而,反射同时带来了性能问题,这就是为什么我试图避免使用它。在我看来,使用支持库是最后的选择,因为它会增加apk的大小。换句话说,如果类加载器在早期加载期间遇到丢失或格式不正确的类文件,它必须等待报告该错误,直到该类首次被程序激活。如果程序从未主动使用该类,则类装入器将永远不会报告错误。似乎只有当类被程序积极使用时才会引发异常。但这是jvm规范,我不确定android上的dalvik vm是如何处理这个问题的。我仍然会使用支持包,而不是编写有条件加载类的代码。V13的支持类只引入了大约400kb的开销。谢谢,这涵盖了android版本4以下的设备。当最小SDK版本大于4时,直接使用SDK_INT是安全的。是的,您可以直接使用SDK_INT