我們使用自定義MyClassLoader
延伸ClassLoader
替換默認PathClassLoader
,如:爲什麼MyFragment由PathClassLoader加載不MyClassLoader
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
加載。這與Context有什麼關係嗎?
在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文件inited包含像A1和C1類。
PathClassLoader
既是MyDexClassLoader
也是MyClassLoader
的父母。
而且在OriginalApk我們原班A1B1C1。
第二問題是,我們可以在loadClass
方法打印,即新A1從PatchDex通過MyDexClassLoader
(由MyClassLoader
稱爲)加載,
但作爲類B1不在PatchDex, MyDexClassLoader
(爲什麼不首先由MyClassLoader
調用)終於可以用它的父(PathClassLoader
)加載老B1,
B1類是直接用C1,所以,我們需要加載CLA ss C1。通過打印loadClass方法,我們發現MyDexClassLoader
已經控制,但不使用它的PatchDex,只是使用父母的PathClassLoader
的舊的C1。
這是怎麼發生的?爲什麼MyDexClassLoader
直接通過它的父級加載C1類,但是它沒有PatchDex?
在此先感謝。
我忘了還有另一個問題,爲什麼'MyClassLoader'不是第一個叫做classloader的呢?有時候'MyDexClassLoader'的'loadClass'直接被調用,而不調用'MyClassLoader'的'loadClass' – oscarthecat