因為項目和團隊的需要蛋济,個人開始對插件化技術預研」鞅睿現(xiàn)在這個技術已經(jīng)在Android開發(fā)領域變得相當?shù)幕馃幔蟾艔?014年開始已經(jīng)有很多優(yōu)秀的流派產(chǎn)生碗旅,到最近的滴滴插件化項目的開源渡处,目前插件化技術越來越成熟。對大型項目從架構到實施都是一種優(yōu)秀的解決方案祟辟。閑話不多說骂蓖,從基數(shù)到深入在學習過程中所需的各方面的知識點在此都一一做個整理。
插件化開發(fā)的優(yōu)勢
1川尖、大型項目業(yè)務繁雜登下,需要多個部門協(xié)同合作。人多則亂叮喳,所以需要合適的架構對業(yè)務進行最大的程度的解耦被芳,插件化可以使各個部門獨立開發(fā)個字業(yè)務的app,同時在需要的情況將各自的應用集成進一個整體的應用中馍悟,使其可以獨立開發(fā)和發(fā)布畔濒,但又可以相互依賴和合并。
2锣咒、應用無需發(fā)布更新侵状,可以通過下載插件或者補丁的方式在后臺完成修復或者更新。
動態(tài)代理在插件化技術中的使用
動態(tài)代理是java設計模式中代理模式的另一種實現(xiàn)毅整,通過JVM在運行期通過反射為委托的接口類動態(tài)的生成代理的一種技術趣兄。目前最火熱的Android網(wǎng)絡請求的開源庫Retrofit就是基于這種技術實現(xiàn)的一款Restful Api風格的Android網(wǎng)絡客戶端框架(本篇主要講的是具體的實例技術在插件化中的應用,所以此處不詳細提悼嫉,但是推薦大家去看下Retrofit源碼艇潭,通過動態(tài)代理去做接口配置的代理,這種設計思想很棒)。
在目前市面上流行的插件化框架中蹋凝,動態(tài)代理同樣被廣泛使用÷尘溃現(xiàn)在我們來看一下最近滴滴才開源的插件化框-VirtualApk中如何使用動態(tài)代理對系統(tǒng)的服務進行hook接管的。
如上圖在demo的MainActivity中鳍寂,加載插件第一步是初始化了插件的管理器PluginManager這個類改含。該類為插件化管理的核心類,將加載的插件放在了一個ConcurrentHashMap中進行管理迄汛。PluginManager.getInstance(base)中實例化了PluginManager并在初始化的時候調用了prepare()方法捍壤。接著看一下這個prepare()方法中的操作。
上圖可以看出隔心,hookSystemServices()方法先通過反射獲取到系統(tǒng)ActivityManagerNative中的IActivityManager接口,然后通過動態(tài)代理的方式尚胞,對IActivityManager接口進行代理硬霍,再用其替換掉系統(tǒng)的達到接管系統(tǒng)服務的目的。我們再看該動態(tài)代理的實現(xiàn)笼裳。
如上圖所示(部分代碼截圖)唯卖,該動態(tài)代理類對需要接管的服務,如:startService等進行了修改和接管躬柬,繞開了系統(tǒng)的限制拜轨,判斷了是否是本地啟動和遠程啟動進行了不同的處理。
關于動態(tài)代理的概念允青,推薦大家參考這篇文章:www.ibm.com/developerworks/cn/java/j-lo-proxy1/index.html
此處startService方法中根據(jù)入?yún)bject[] args數(shù)組(代理對應方法的入?yún)?shù)數(shù)組橄碾,此處是IActivityManager接口中方法startService(IApplicationThread caller, Intent service,String resolvedType, String callingPackage,int userId)的入?yún)ⅲ┤^(qū)分來源為本地或插件服務來進行不同的分發(fā)操作。
總結
代理模式在JAVA中廣泛的應用颠锉,是AOP編程的一種實現(xiàn)手段法牲。本文只是列舉了動態(tài)代理技術在插件化框架中的某個功能的實現(xiàn)。其實不管是動態(tài)代理還是靜態(tài)代理琼掠,在插件化框架中都有大量的使用去繞過系統(tǒng)的限制達到加載插件去執(zhí)行宿主中的功能拒垃。大家可以先從Android Activity等服務的啟動流程的源碼閱讀去更深入的了解系統(tǒng)服務的運行過程,從而找到合適的切入點去代理系統(tǒng)的服務達到自己的定制化需求瓷蛙。此外悼瓮,JVM的動態(tài)代理技術只能代理接口,原因是在代理類最后都繼承了Proxy這個類艰猬,根據(jù)Java的單一繼承規(guī)則横堡,所以只能為接口動態(tài)代理。如果想對抽象類或者類做動態(tài)代理可以采取cglib來實現(xiàn)冠桃,具體的就不在本文中討論了翅萤,大家可以查找相關的實現(xiàn)或自己去嘗試。關于插件化中使用到的其他技術,我會一邊學習一邊分享給大家套么,后續(xù)會整理出對應的demo培己。
引用
VirtualApk:github.com/didi/VirtualAPK
動態(tài)代理的概念:www.ibm.com/developerworks/cn/java/j-lo-proxy1/index.html