騰訊Bugly熱更新整合以及問題
阿新 • • 發佈:2018-11-21
ClassLoader
我們知道Java在執行時載入對應的類是通過ClassLoader來實現的,ClassLoader本身是一個抽象來,Android中使用PathClassLoader類作為Android的預設的類載入器,
PathClassLoader其實實現的就是簡單的從檔案系統中載入類檔案。PathClassLoade本身繼承自BaseDexClassLoader,BaseDexClassLoader重寫了findClass方法,
該方法是ClassLoader的核心
@Override protected Class<?> findClass(String name) throws ClassNotFoundException { List<Throwable> suppressedExceptions = new ArrayList<Throwable>(); Class c = pathList.findClass(name, suppressedExceptions); if (c == null) { ClassNotFoundException cnfe = new ClassNotFoundException("Didn't find class \"" + name + "\" on path: " + pathList); for (Throwable t : suppressedExceptions) { cnfe.addSuppressed(t); } throw cnfe; } return c; }
看原始碼可知,BaseDexClassLoader將findClass方法委託給了pathList物件的findClass方法,pathList物件是在BaseDexClassLoader的建構函式中new出來的,
它的型別是DexPathList。看下DexPathList.findClass原始碼是如何做的:
public Class findClass(String name, List<Throwable> suppressed) { for (Element element : dexElements) { DexFile dex = element.dexFile; if (dex != null) { Class clazz = dex.loadClassBinaryName(name, definingContext, suppressed); if (clazz != null) { return clazz; } } } if (dexElementsSuppressedExceptions != null) { suppressed.addAll(Arrays.asList(dexElementsSuppressedExceptions)); } return null; }
直接就是遍歷dexElements列表,然後通過呼叫element.dexFile物件上的loadClassBinaryName方法來載入類,如果返回值不是null,就表示載入類成功,會將這個Class物件返回。
而dexElements物件是在DexPathList類的建構函式中完成初始化的。
根據以下詳細操作即可
1 熱更新:使用Bugly整合的Tinker - 簡書 https://www.jianshu.com/p/fed9b2cddafe
2 熱更新實踐:Bugly熱更新打包及修復 - 簡書 https://www.jianshu.com/p/10571ca6571e
其中注意的註冊我採用的是第二個方法成功
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// 這裡實現SDK初始化,appId替換成你的在Bugly平臺申請的appId
// 除錯時,將第三個引數改為true
Bugly.init(this, "900029763", false);
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// you must install multiDex whatever tinker is installed!
MultiDex.install(base);
// 安裝tinker
Beta.installTinker();
}
}