我正在开发一个需要从中央服务器频繁更新的 Android 库。我在想,如果我的库可以自我更新,或者我可以发布一个引导库,在安装应用程序时下载目标库,那该多好。
我在 1.5 中看到了这个名为“DexClassLoader”的类,但除了 API 文档之外,网络上似乎很少有宝贵的东西。有没有人成功地将它用于我描述的场景?
另外,Android Market 的条款是否允许这样的事情?
我正在开发一个需要从中央服务器频繁更新的 Android 库。我在想,如果我的库可以自我更新,或者我可以发布一个引导库,在安装应用程序时下载目标库,那该多好。
我在 1.5 中看到了这个名为“DexClassLoader”的类,但除了 API 文档之外,网络上似乎很少有宝贵的东西。有没有人成功地将它用于我描述的场景?
另外,Android Market 的条款是否允许这样的事情?
我已经成功使用了 DexClassLoader。重要的是提供一个dexOutputDir
实际上可由您的应用程序编写的,所以不是 /data/dalvik-cache
. 否则,日志将显示一两行关于未能在此处写入的信息,然后是ClassNotFoundException
.
cl = new DexClassLoader("/full/path/com.example.apk",
getFilesDir().getAbsolutePath(),// /data/data/foo/files
null, // native lib path, I haven't used this
MyClass.class.getClassLoader());
// This doesn't make Class.forName() work, instead I do this:
Class<?> foo = cl.loadClass("com.example.foo");
为了Class.forName()
工作,您可以尝试Thread.setContextClassLoader()(我没有)。
确实,您想要的东西得到支持并且有效。DexClassLoader对我来说没有按预期工作,但以下代码工作正常。
DexFile df = new DexFile(new File("/data/app/my_downloaded_lib.apk"));
ClassLoader cl = getClassLoader();
Class clazz = df.loadClass("com/my/lib/MyClass", cl);
关于市场问题,我认为这没有任何问题,但您必须阅读 EULA 才能确定。
DexClassLoader
是正确的答案。应用程序永远不应该DexFile
直接使用(它应该由类加载器使用)。
您可以将外部存储 ( /sdcard
) 或应用程序的私有数据区域用于dexOutputDir
参数。外部存储通常较大,但如果卡被弹出,您的应用程序将被终止,并且由于缺乏文件权限强制执行,第三方很容易替换您的代码。这可能允许恶意应用程序导致您的应用程序执行任意操作。(如果你想这样做,通过Environment.getExternalStorageDirectory()
; 获取路径需要WRITE_EXTERNAL_STORAGE
许可。)
应用程序私有数据区(从 获取路径Context.getFilesDir()
)更安全,并且还具有在卸载应用程序时自动清理的优点。这是推荐的方法。