我正在用dexclassloader做一些测试,看看是否可以用新功能“更新”我的应用程序。目前我已经有了这个测试方法,它可以与testClass一起工作并运行test()方法。我想知道的是,我如何“替换”或“更新”和已经存在的类。?欢迎提出任何意见或其他建议。
方法:
public static void loadExtLib(String pathDexFile, Context ctx) {
String temp = ctx.getDir("temp", 0).toString();
DexClassLoader classLoader = new DexClassLoader(pathDexFile,
temp, null, ctx.getClass().getClassLoader());
String testClass = "com.mystudio.myapp.TestClass";
Class<?> libProviderClass = null;
try {
libProviderClass = classLoader.loadClass(testClass);
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
try {
Method m = libProviderClass.getDeclaredMethod("test", null);
try {
m.invoke(libProviderClass, null);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} catch (NoSuchMethodException e1) {
e1.printStackTrace();
}
Log.v("loadClass", "loaded: " + testClass);
}
最佳答案
通常不能“替换”或“更新”类;只有由DexClassLoader
或其子加载程序之一加载的类才能看到加载的类。例如,您不能将java.lang.String
替换为一个版本,该版本会做一些邪恶的事情来规避类中的安全限制。
这在一定程度上降低了加载多个同名类的实用性。另一方面,它确保类加载器A的操作独立于类加载器B的操作,只要其中一个不是另一个的父级。
使用运行时加载类的一种可能有用的方法是在基本加载程序中定义一个接口,该接口由类的“旧”和“新”版本实现。通过接口引用类的实例,可以避免“旧”代码看不到“新”类定义的事实。
(考虑这一点的最好方法是在思想上用类加载器标记每个类。很明显,您不能将String'new
传递给为String'old
编写的函数,但是如果它们都实现了CharSequence'old
,那么您可以始终通过它引用它们。)
在dalvik测试中有一些代码用于执行运行时“替换”,可能有助于通读。参见068-classloader测试。src
和src-ex
的内容构建在单独的.jar文件中;后者在运行时加载。
关于android - DexClassLoader-添加功能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18466996/