Small插件化源碼分析--啟動(dòng)流程

我系蒼王。

這個(gè)系列的課程都是時(shí)下最熱門的開源框架的源碼分析。

今次為大家?guī)淼氖荢mall的源碼分析

一個(gè)源碼代碼量這么大,究竟從哪里開始分析才好呢?

最想了解究竟是哪個(gè)github的有源碼模塊呢?

歡迎在留言區(qū),我們共同討論分享的源碼分析。


歡迎瀏覽我之前的文章,有興趣可以參考一下,可以給個(gè)喜歡或者關(guān)注我的文章,謝謝。

[Android]如何做一個(gè)崩潰率少于千分之三噶應(yīng)用app(9)-Small插件化

Small插件化源碼分析--啟動(dòng)流程

Small插件化源碼分析--熱更流程


一.Small的啟動(dòng)

1.首先了解一下Small的基本情況Small

?基本的使用方法,我在我的[Android]如何做一個(gè)崩潰率少于千分之三噶應(yīng)用app(9)-Small插件化這個(gè)文件有基礎(chǔ)使用分析。

2.然后我們需要更深入了解Small的流程的話,你可以看到 github里面有提供DevSample的文件夾,這才是真正源碼存在的地方。

你可以到Small最主要的源碼

3.首先分析一下Small的啟動(dòng)流程

查看一下Application的代碼

Small.java是全部調(diào)用方法的入口,一般聲明為靜態(tài)方法。

setBaseUri設(shè)定基本的跳轉(zhuǎn)地址

setWebViewClient設(shè)置網(wǎng)頁的基本回調(diào)

Small.preSetup設(shè)定Small啟動(dòng)的預(yù)設(shè)置

(1)registerLauncher注冊BundleLauncher到一個(gè)List里面

? ? ? ?ActivityLauncher, ApkBundleLauncher,WebBundleLauncher都繼承BundleLauncher抽象類

? ? ? ?ActivityLauncher是Activity的管理類

? ? ? ?這里需要說明一下,Small依然是使用占坑的方式來事先聲明Actvity,這是很多插件化相同的做法

? ? ? ?ApkBundleLauncher是bundle加載的管理類

? ? ? ?WebBundleLauncher應(yīng)該是web頁面的管理類

? (2) ?回調(diào)用Bundle.onCreateLaunchers初始化每一個(gè)laucher

? ? ? 這里會(huì)調(diào)用ApkBundlesLauncher里面的onCreate函數(shù)

? ? ? 通過getActivityThread反射獲取ActivityThread的對象

? ? ? 反射獲取mInstumentation的屬性對象和再將自定義的InstrumentationWrapper替換掉原來的mInstumentation

? 這里會(huì)反射mCallback的對象替換成ActivityThreadHandlerCallback

? ? ? ?獲取App的provider列表

? ? ? ? 保存這些變量用于全局控制


(2)接下來是檢測是不是第一次啟動(dòng)或者更新,去檢測他的bundle的版本號(hào)

(3)然后獲取一些簽名的信息保存到sHostCertificates

4.Application啟動(dòng)完成后LaunchActivity就是啟動(dòng)頁就會(huì)開始初始化

?在onStart的聲明周期里調(diào)用Small.Setup的方法初始化,結(jié)束回調(diào)啟動(dòng)Bundle里面聲明main的類

(1)她會(huì)調(diào)用Bundle里面的loaderLaunchableBundles的函數(shù)

? ? ? ? ? ? 然后啟動(dòng)一個(gè)LoadBundleThread的線程加載

? ? ? ? ? ? ? ? ?然后調(diào)用setupLaunchers的函數(shù)啟動(dòng)之前注冊的launcher的setup函數(shù)

(1)ActivityLauncher setUp是初始化一些已經(jīng)注冊號(hào)的Activity,加到sActivityClasses里面

(2)ApkBundleLauncher的setUp是是通過代理替換InvocationHandler,有看過Activity啟動(dòng)的相關(guān)源碼都應(yīng)該知道是同過代理的方式封裝啟動(dòng)的,這里面會(huì)通過wrapIntent的函數(shù)重新包裝intent替換成占坑的里面的Activity

通過記錄realClazz和sLoaderAcitivities里面匹配封裝intent

(3)WebBundleLauncher的setUp的方法,啟動(dòng)一個(gè)新的android 本身的WebView

在Bundle.setupLaunchers的函數(shù)完成之后才會(huì)調(diào)用loadBundles

這里的getPatchManifestFile是獲取bundle.json這個(gè)文件

將bundle.json轉(zhuǎn)換成mainfestJson的String字符串

然后繼續(xù)調(diào)用loadBundles的方法

這里會(huì)繼續(xù)調(diào)用prepareForLaunch的方法

這里會(huì)繼續(xù)調(diào)用preloadBundle的方法來判斷,然后調(diào)用loadBundle方法

(1)調(diào)用ApkBundleLauncher的loadBundle方法,會(huì)獲取bundle的包名,來初始化LoadedApk的一些信息

(2)還有AssetBundleLauncher(WebBundleLauncher繼承于它)的loadBundle

判斷是否可以轉(zhuǎn)換為可以調(diào)整的url地址

我們在Bundle.loadBundles的方法往下看,可以看到它會(huì)再分發(fā)到各個(gè)launcher在啟動(dòng)加載

它會(huì)跳轉(zhuǎn)到ApkBundleLauncher作一些加載資源,dex和lib的一些操作

(1)這里可以看到它會(huì)調(diào)用ReflectAcclerator.mergeResources調(diào)用合并資源

? ? 通過addAssetPaths的方法反射把資源放到newAssetManager里面

? 然后反射資源到resource到mResourcesImpl的代理屬性里面

(2)使用ReflectAcclerator.ExpandDexPathList的方法來合并加載dex的列表

? ? ? ? 這里會(huì)通過makeDexElement來返回Elements的數(shù)組

然后通過fillDexPathList的方法來反射一些地址

然后最后通過expandArray的方法,里面通過System.arraycopy的方法來寫入dex的內(nèi)容

(3)加載完resource和dex之后,會(huì)再加載lib,這里會(huì)調(diào)用ReflectAcclerator.ExpandNativeLibraryDirectoris的方法

?這里依然是反射一些lib的相關(guān)地址屬性,然后調(diào)用expandArray來完成加載

(4)這里還會(huì)加載Provider的內(nèi)容,直接就通過反射完成

Small的SetupProvider已經(jīng)在AndroidMainfest里面有聲明了,所以這里加載只是因?yàn)锳pkBundleLaucher.onException添加的容錯(cuò)處理(SetupProvider加載失敗的時(shí)候)

寫到這里,啟動(dòng)的流程基本就到這里了。

下一節(jié)我這里會(huì)介紹Small的更新流程的源碼。

敬請期待!!!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容