[Android]用架構(gòu)師角度看插件化(2)-Replugin 唯一hook點

大家好,我系蒼王。

以下是我這個系列的相關(guān)文章,有興趣可以參考一下,可以給個喜歡或者關(guān)注我的文章。

[Android]用架構(gòu)師角度看插件化--章節(jié)列表


Replugin,為何我選擇要研究這個的插件呢?很大的原因是因為它的介紹中說明,他只會有一個hook點。


一.Hook

hook點是什么?

我們?nèi)腴TAndroid的時候,一定會看到過這個圖,但是你確定深刻了解到這個圖的嗎?

我們試著換著思維,用組件化的角度去看這張圖,你會發(fā)現(xiàn)其層級依賴關(guān)系,與組件化的工程是非常類似的。(當然你看得角度不同,我只能說是類似)

倘若你用插件的思想來看,我們上層的眾多應(yīng)用(Applications)就是作為framewrok層的插件一樣的存在。(Framework作為宿主一樣的存在,只是它是對于應(yīng)用們,他說了算,基于安全管理和效率,他能限制你們獲取資源的權(quán)限和方法)

然后我們想要在獨自的應(yīng)用中做得像Framework層一樣的加載應(yīng)用,我們本身就享用了Framework層對資源等的加載機制。如果我們想要將某些資源加載,加載驗證,權(quán)限限制等繞開,運用到手機本身Framework來完成,就會涉及到hook了。

以我理解:hook,當Framework運行時,攔截并替換掉Framework層中某些原生的方法或?qū)ο?,讓其運行到我們想要的效果。


滴滴的VirtualApk 會hook掉AMS(ActivityManagerService)和Instumentation,這兩個Framework的文件非常重要,AMS是四大組件的入口,管理生命周期,管理應(yīng)用通信等,Instumentation管理了Activity的生命周期的調(diào)用。有興趣可以深入去看這兩個Framework文件。而其他舊式插件化,還會hook掉一下Service,Broadcast的機制。

而Replugin卻走的是完全和傳統(tǒng)插件化不同的路,它hook掉的是ClassLoader,而且它只有唯一的hook點。


hook為何會不安全?

就是攔截和替換原生機制,因為Android的機型太多了,而且是開源的,那么各個廠商定制Rom的修改,不同版本的適配也是非常大的阻礙,倘若替換掉某些廠商修改Google原生Android的源碼里面的方案,2??剛好hook點沒有兼容這方面的源碼,就有引起hook失敗或者崩潰的可能性。

意味著hook點越少,其可能產(chǎn)生修改的代碼會變小,維護的代價會變小,耗損的人力資源就會變少,整個用戶體驗就會提升。

架構(gòu)的標準,是要懂得,衡量 時間+空間+效率。唯一hook點,暫時Replugin應(yīng)該是插件化hook點的極致了。



二.ClassLoader

對于Android 的ClassLoader,請認真仔細看下圖,一張圖為你解答各種疑問。

此圖非常形象的說明Android里面ClassLoader的架構(gòu)。

這里一般插件化框架,都是使用DexClassLoader動態(tài)加載dex文件。

DexClassLoader可以加載apk,dex,jar,還有zip后綴格式的文件,其最終應(yīng)該是加載dex文件,這也是我QQ群中驗證問題的答案。

BaseDexClassLoader,里面有一個DexPathList對象,是用來保存dex的列表的,而查詢dex里面的資源、class都是在這個列表中遍歷dex對象。

而Replugin是特別的其使用自定義的PathClassLoader來加載apk中的dex,其有別于其他插件框架。


三.唯一hook點

我們看一下Replugin的加載過程。

用的是官網(wǎng)的replugin-host-library為例子

Application中attachBaseContext是最快執(zhí)行的,其調(diào)用了Replugin.App.attachBaseContext方法

他會調(diào)用到PMF這個類init方法,PMF是框架和住程序接口

其里面會調(diào)用pluginManger的初始化,還有PatchClassLoaderUtils.patch的方法。

PatchClassLoaderUitls這個類是修改宿主和私有屬性的位置,其實就是那個唯一的hook點的位置

可以看到在patch中需要獲取到整個application的context對象。

然后生成自己的classLoader對象,去hook掉mClassLoader對象,F(xiàn)ieldUtils是對Java反射機制的封裝,以后使用到發(fā)射的時候,可以參考一下這里的封裝,感覺是迄今看到眾多插件化的封裝最完善的。

這里的對參數(shù)的說明很清晰,最終會返回RePluginClassLoader對象。

這里調(diào)用到RepluginClassLoader里面,copyFromOrginal會將一些需要更改的屬性去掉final屬性,才能開始修改。initMethods,反射來替換掉ClassLoader的方法

里面替換掉四個方法,findResource和findResources是資源的獲取,findLibrary是庫獲取,getPackage就是獲取包信息了。

這里MethodUtils是方法反射的封裝,也是封裝得非常好。

在Android源碼中,是通過DexPathList中讀取資源,Resource是以URL格式返回,而lib庫是用String返回

包獲取是在classLoader中完成的

這里你會發(fā)現(xiàn)有點矛盾的地方,因為有可能不是那么容易一下子能看明。

我們前面看到需要反射出一些BaseDexLoader的一些方法

但是你看到其繼承調(diào)用的時候,卻使用了一模一樣的方法,這樣不就用了一模一樣的流程了?這有何意義?

這里其實意義就在于其傳入的mOrig參數(shù),這個參數(shù)是classLoader的對象,而不同插件間都有classloader,那么其分別調(diào)用插件間的classloader資源的時候,就需要在這里攔截調(diào)用。


以上就是對Replugin的唯一hook點的分析。

值得借鑒的地方。

(1)唯一hook點,是用hook掉足夠大的ClassLoader對象,來讓資源加載得到更加便利。

(2)Java反射機制的整合FieldUtils域反射封裝和MethodUtils方法反射封裝。


這里發(fā)一條廣告,我創(chuàng)立了一個小密圈。

每天會分享java基礎(chǔ),組件化插件化相關(guān),音視頻開源項目分享。

最重要,帶有群員們珍貴的分析和點評。

還有最新插件化框架的分析和運用,組件化架構(gòu)技巧的分享,都盡在這里。

不需要一頓飯的價錢 ,68/一整年的學習資料。

付費是真干貨,真正節(jié)省時間的通往技術(shù)的途徑。

來到這里希望影響你的不只是技術(shù)提升,而且是人生的架構(gòu)的導向。

成立兩周已經(jīng)有超過190+的小伙伴加入了我們的行列了,并且持續(xù)增加,讓我們一起成長,群內(nèi)還有不定時福利,包括原創(chuàng)書籍的福利哦。

我建立了一個關(guān)于Android架構(gòu)學習的群,里面可以進一步進行組件化學習的交流。

群號是316556016,也可以掃碼進群。我在這里期待你們的加入?。?!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,765評論 25 709
  • 最近幾年移動開發(fā)業(yè)界興起了「 插件化技術(shù) 」的旋風,各個大廠都推出了自己的插件化框架,各種開源框架都評價自身功能優(yōu)...
    斜杠時光閱讀 4,098評論 1 36
  • 時間都去那兒了?現(xiàn)在很多人抱怨,時間不夠用。工作效率低下,注意力不集中。 那時間都花哪兒了呢?手機成了罪魁禍首。每...
    勵恩閱讀 408評論 0 0
  • 設(shè)*可以匹配0~n個任意字符,?可以匹配一個任意字符,實現(xiàn)字符串含通配符的匹配算法,查找算法 參考閱讀 c語言實現(xiàn)...
    yuansip閱讀 1,956評論 0 0
  • 哈哈,今天作業(yè)是簡單的水果。
    始于初見2017閱讀 242評論 1 1

友情鏈接更多精彩內(nèi)容