【发布时间】:2016-07-15 11:39:17
【问题描述】:
我们正在使用自定义MyClassLoader 扩展ClassLoader 来替换默认PathClassLoader,例如:
Context mBase = (Context) getFieldValue(application, "mBase");
Object mPackageInfo = getFieldValue(mBase, "mPackageInfo");
ORIGINAL_CLASS_LOADER = (ClassLoader) getFieldValue(mPackageInfo, "mClassLoader");
CUSTOMED_CLASS_LOADER = new MyClassLoader(ORIGINAL_CLASS_LOADER);
在应用程序 onCreat 时执行。
第一个问题是,并不是所有的类都是由MyClassLoader首先加载的,只是MyActivitys和MyViews是由MyClassLoader加载的,MyFragments仍然是由PathClassLoader加载的。这和上下文有关吗?
在MyClassLoader我们加载类
public Class<?> loadClass(String className)
throws ClassNotFoundException {
try {
ClassLoader myDexClassLoader = loaders.get("DEX");
if(myDexClassLoader != null){
Class<?> c = null;
try {
c = myDexClassLoader.loadClass(className);
// c = loader.findClass(className);
} catch (ClassNotFoundException e) {
}
if (c != null) {
return c;
}
}
}
return super.loadClass(className);
}`
而myDexClassLoader被定义为
public static class MyDexClassLoader extends DexClassLoader {
public MyDexClassLoader(String dexPath, String dexOutputDir,
String libPath, ClassLoader parent) {
super(dexPath, dexOutputDir, libPath, parent);
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
return super.findClass(name);
}
@SuppressLint("NewApi")
@Override
public Class<?> loadClass(String className)
throws ClassNotFoundException {
Class<?> clazz = null;
try {
clazz = findClass(className);
} catch (ClassNotFoundException e) {
}
if (clazz != null) {
return clazz;
}
return super.loadClass(className);
}
}
MyDexClassLoader 使用 PatchDex 文件初始化,其中包含 A1 和 C1 等类。
PathClassLoader 是 MyDexClassLoader 和 MyClassLoader 的父级。
在 OriginalApk 我们有原始类 A1 B1 C1。
第二个问题是,我们可以在loadClass方法中打印,new A1是由MyDexClassLoader(由MyClassLoader调用)从PatchDex加载的,
但是由于类 B1 不在 PatchDex 中,MyDexClassLoader(为什么不首先由 MyClassLoader 调用)最终使用它的父级(PathClassLoader)来加载 旧 B1 ,
类 B1 直接使用 C1,所以我们必须加载类 C1。通过 print loadClass 方法我们发现 MyDexClassLoader 已经控制了,但是没有使用它的 PatchDex,只是使用了 parent 的 PathClassLoader 的 old C1。
这是怎么发生的?为什么MyDexClassLoader直接通过它的父类加载C1,而不是它的PatchDex?
提前致谢。
【问题讨论】:
-
我忘了还有一个问题,为什么
MyClassLoader不是第一个调用的类加载器?有时直接调用MyDexClassLoader的loadClass而不调用MyClassLoader的loadClass
标签: android classloader patch