定義
加載so文件
加載dex/jar/apk文件
動態(tài)加載的基礎(chǔ)就是classloader,一個app中至少需要兩個classloader,一個用來加載系統(tǒng)本身的類:bootclassloader;另一個用來加載app本身需要的一些類:pathclassloader慨默。
- 雙親代理模型
ClassLoader(ClassLoader parentLoader, boolean nullAllowed) {
if (parentLoader == null && !nullAllowed) {
throw new NullPointerException("parentLoader == null && !nullAllowed");
}
parent = parentLoader;
}
從代碼中可以得出阿宅,在構(gòu)造自己的classLoader時狭魂,需要提供一個ClassLoader類型的參數(shù)parentLoader猖闪,通過這種構(gòu)造方式吹榴,可以將一個應(yīng)用程序胧洒,乃至整個android系統(tǒng)中所有的classloader通過一個樹連接到一起畏吓,這就是ClassLoader的雙親代理模型
- loadClass
android系統(tǒng)通過loadClass加載dex中的類墨状。loadClass的實(shí)現(xiàn)如下
public Class<?> loadClass(String className) throws ClassNotFoundException {
return loadClass(className, false);
}
protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException {
Class<?> clazz = findLoadedClass(className);
if (clazz == null) {
ClassNotFoundException suppressed = null;
try {
clazz = parent.loadClass(className, false);
} catch (ClassNotFoundException e) {
suppressed = e;
}
if (clazz == null) {
try {
clazz = findClass(className);
} catch (ClassNotFoundException e) {
e.addSuppressed(suppressed);
throw e;
}
}
}
return clazz;
}
從代碼中可以看到,loadClass的代碼邏輯是:
- 通過findLoadedClass判斷將要被加載的類className是否已經(jīng)被加載過菲饼,如果被加載過則返回結(jié)果肾砂,沒有被加載則繼續(xù)執(zhí)行代碼
- 如果類className沒有被加載過,則查看它的父節(jié)點(diǎn)有沒有加載這個類宏悦,如果有則返回結(jié)果镐确,如果沒有則繼續(xù)
- 調(diào)用findClass方法查找類,查找到則返回結(jié)果饼煞,未查找到則拋出異常源葫。
通過loadClass的代碼邏輯可以看到,這整個是一個遞歸算法派哲,首先查看自己是否加載過該類臼氨,然后查看父節(jié)點(diǎn)是否加載過這個類,通過遞歸可以遍歷這個節(jié)點(diǎn)以上的所有節(jié)點(diǎn)芭届。
DexClassLoader可以加載未安裝的apk以及sd卡上的jar包储矩,dex等
PathClassLoader只能加載系統(tǒng)中已經(jīng)安裝過的apk
DexClassLoader能夠加載sd卡上的內(nèi)容的原因是DexClassLoader可以自己指定optimizedDirectory為Null,而PathClassLoader則不能指定optimizedDirectory為空褂乍。
- 好處
根據(jù)前邊的分析可以知道持隧,類加載器 - 壞處