Android 插件化開發(fā)(一) - 動態(tài)代理

因為項目和團(tuán)隊的需要,個人開始對插件化技術(shù)預(yù)研?,F(xiàn)在這個技術(shù)已經(jīng)在Android開發(fā)領(lǐng)域變得相當(dāng)?shù)幕馃幔蟾艔?014年開始已經(jīng)有很多優(yōu)秀的流派產(chǎn)生,到最近的滴滴插件化項目的開源,目前插件化技術(shù)越來越成熟。對大型項目從架構(gòu)到實施都是一種優(yōu)秀的解決方案。閑話不多說,從基數(shù)到深入在學(xué)習(xí)過程中所需的各方面的知識點在此都一一做個整理。

插件化開發(fā)的優(yōu)勢

1、大型項目業(yè)務(wù)繁雜,需要多個部門協(xié)同合作。人多則亂,所以需要合適的架構(gòu)對業(yè)務(wù)進(jìn)行最大的程度的解耦,插件化可以使各個部門獨立開發(fā)個字業(yè)務(wù)的app,同時在需要的情況將各自的應(yīng)用集成進(jìn)一個整體的應(yīng)用中,使其可以獨立開發(fā)和發(fā)布,但又可以相互依賴和合并。

2、應(yīng)用無需發(fā)布更新,可以通過下載插件或者補丁的方式在后臺完成修復(fù)或者更新。

動態(tài)代理在插件化技術(shù)中的使用

動態(tài)代理是java設(shè)計模式中代理模式的另一種實現(xiàn),通過JVM在運行期通過反射為委托的接口類動態(tài)的生成代理的一種技術(shù)。目前最火熱的Android網(wǎng)絡(luò)請求的開源庫Retrofit就是基于這種技術(shù)實現(xiàn)的一款Restful Api風(fēng)格的Android網(wǎng)絡(luò)客戶端框架(本篇主要講的是具體的實例技術(shù)在插件化中的應(yīng)用,所以此處不詳細(xì)提,但是推薦大家去看下Retrofit源碼,通過動態(tài)代理去做接口配置的代理,這種設(shè)計思想很棒)。

在目前市面上流行的插件化框架中,動態(tài)代理同樣被廣泛使用。現(xiàn)在我們來看一下最近滴滴才開源的插件化框-VirtualApk中如何使用動態(tài)代理對系統(tǒng)的服務(wù)進(jìn)行hook接管的。

load plugin

如上圖在demo的MainActivity中,加載插件第一步是初始化了插件的管理器PluginManager這個類。該類為插件化管理的核心類,將加載的插件放在了一個ConcurrentHashMap中進(jìn)行管理。PluginManager.getInstance(base)中實例化了PluginManager并在初始化的時候調(diào)用了prepare()方法。接著看一下這個prepare()方法中的操作。

hookService 圖1


hookService 圖2

上圖可以看出,hookSystemServices()方法先通過反射獲取到系統(tǒng)ActivityManagerNative中的IActivityManager接口,然后通過動態(tài)代理的方式,對IActivityManager接口進(jìn)行代理,再用其替換掉系統(tǒng)的達(dá)到接管系統(tǒng)服務(wù)的目的。我們再看該動態(tài)代理的實現(xiàn)。

proxy 圖1
proxy 圖2
proxy 圖3

如上圖所示(部分代碼截圖),該動態(tài)代理類對需要接管的服務(wù),如:startService等進(jìn)行了修改和接管,繞開了系統(tǒng)的限制,判斷了是否是本地啟動和遠(yuǎn)程啟動進(jìn)行了不同的處理。

關(guān)于動態(tài)代理的概念,推薦大家參考這篇文章:www.ibm.com/developerworks/cn/java/j-lo-proxy1/index.html

此處startService方法中根據(jù)入?yún)bject[] args數(shù)組(代理對應(yīng)方法的入?yún)?shù)數(shù)組,此處是IActivityManager接口中方法startService(IApplicationThread caller, Intent service,String resolvedType, String callingPackage,int userId)的入?yún)ⅲ┤^(qū)分來源為本地或插件服務(wù)來進(jìn)行不同的分發(fā)操作。

總結(jié)

代理模式在JAVA中廣泛的應(yīng)用,是AOP編程的一種實現(xiàn)手段。本文只是列舉了動態(tài)代理技術(shù)在插件化框架中的某個功能的實現(xiàn)。其實不管是動態(tài)代理還是靜態(tài)代理,在插件化框架中都有大量的使用去繞過系統(tǒng)的限制達(dá)到加載插件去執(zhí)行宿主中的功能。大家可以先從Android Activity等服務(wù)的啟動流程的源碼閱讀去更深入的了解系統(tǒng)服務(wù)的運行過程,從而找到合適的切入點去代理系統(tǒng)的服務(wù)達(dá)到自己的定制化需求。此外,JVM的動態(tài)代理技術(shù)只能代理接口,原因是在代理類最后都繼承了Proxy這個類,根據(jù)Java的單一繼承規(guī)則,所以只能為接口動態(tài)代理。如果想對抽象類或者類做動態(tài)代理可以采取cglib來實現(xiàn),具體的就不在本文中討論了,大家可以查找相關(guān)的實現(xiàn)或自己去嘗試。關(guān)于插件化中使用到的其他技術(shù),我會一邊學(xué)習(xí)一邊分享給大家,后續(xù)會整理出對應(yīng)的demo。

引用

VirtualApk:github.com/didi/VirtualAPK

動態(tài)代理的概念:www.ibm.com/developerworks/cn/java/j-lo-proxy1/index.html

最后編輯于
?著作權(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,828評論 25 709
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,525評論 19 139
  • 引言 先簡單介紹一下Android插件化。很早之前已經(jīng)有公司在研究這項技術(shù),淘寶做得比較早,但淘寶的這項技術(shù)一直是...
    流水潺湲閱讀 12,298評論 8 149
  • 我發(fā)現(xiàn)我對自己越來越?jīng)]有自信了,也的確有太多事情,事實證明自己越來越做不好了!曾經(jīng)覺得自己教學(xué)能力雖不會大言不慚地...
    薛薛閑扯閱讀 143評論 0 0
  • 文/雪諾 微信公眾號:迷茫人生路 還有幾天就二十三了,在我年少的日子里二十三是一個多么好的年紀(jì)啊,有自由、...
    Snow鳳閱讀 574評論 0 0

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