[Android組件化]組件化與插件化優化

如下是我這個系列的相關文章,有興趣能夠參考一下,能夠給個喜歡或者關注個人文章。
算法

[Android]如何作一個崩潰率少於千分之三噶應用app--章節列表api


記得我以前有介紹了一種很是適合於組件化後作插件化的框架,就是Small。服務器

我在第九章節的時候就有介紹了Small的使用,還有深刻分析Small的運行原理架構

近來使用Small研發插件中,遇到一些問題,就在這裏和你們討論一下。app

這裏說一下Small的的一些缺陷,框架

(1)其不支持動態Service,Service都只能放在宿主裏面了。組件化

(2)Small暫時是隻能經過冷更新(就是徹底重啓App時才能加載,若是有更新,當你按home鍵或者返回鍵退出,其會將整個Process殺死重啓),源碼中木有在運行途中增學習


這一篇的簡書,理解難度將會加大,由於公司代碼就不宜張貼啦,若是同窗沒有項目木有實現過插件化的,理解起來會有必定的瓶頸。gradle

1.關於插件化選型

能夠參考如下文章lua

基礎看

Android客戶端插件化熱修復各類方案對比和最全總結

深刻看這個

Android插件化從入門到放棄-最強合集

估計看完這些你就快能夠瘋掉了。^_^

選型基本須要考慮的問題

1.對四大組件的支持(hook點支持)

2.so庫支持

3.打包時資源衝突

4.更新方式和時機


2.插件間通訊

每一個插件都是基於base的module去開發,那麼經過這個base module那麼咱們就能夠經過ModuleBus或者路由的機制完成傳輸了。

Small自己定義的OpenUri來啓動對應的模塊,並未有提供能夠傳遞各類參數的方法。

而咱們是經過自定義一個PluginManager封裝,相似以前介紹的分發機制去封裝一個方法標誌字符串標誌,而後傳輸intent,context,viewgroup等對象,經過PluginManager遍歷過濾再傳輸到對應的插件模塊,其餘須要傳輸的信息均可以封裝到intent裏面。


3.資源冗餘問題

你想像一下,若是你每一個工程會依賴baseApi,那麼編譯生成的base 的module,當生成xxx.so文件的時候,不就會出現一份冗餘的base module代碼和資源嗎?

這個問題其實Small有自定義的編譯代碼,其本身寫了一套編譯的groovy代碼,因此在編譯的時候重複依賴的module移除了。

Small的編譯代碼,若是沒點gradle構建工程基礎和groovy編譯想法的確不容易找到

我這裏簡單指明一下吧

以前說了使用DevSample查看Small的源碼,這裏編譯的最終配使用的是AppPlugin


而後能夠看到解決依賴的方法經過,過濾掉D.txt裏面的所要依賴的


經過app-D.txt compile.exclude掉這些依賴的庫


經過afterEvaluate最終加載這個過濾方法。


AppPlugin這裏也會有將每一個module裏面生成的R.txt重複的資源id過濾掉,還有保留public.txt的id

這裏publicEntries是保存的public.txt裏面的內容,而bundle.Entries保存的是R.txt的內容的


bundleEntries是過濾掉重複的R id的算法。


若是不熟悉Gradle構建流程,也不打算深刻了解的,就不須要深究了。

這裏只要知道,每一個module都編譯的時候都共有一份D.txt R.txt和public.txt,而後small的構建會過濾掉相同的資源。而後編譯出來的so文件插件運行的時候,仍是經過同樣的資源id來索引到公用的base module的內容。

那麼爲了加強每一個功能模塊的獨立性,每一個功能module都獨立成爲一個工程(Small的這個工程模塊只是獨立成一個module),那麼要怎麼處理才能使工程都去除資源重複呢?

這裏其實也很簡單,咱們保證咱們都依賴的自定義擴展的Small庫,base的module是被宿主module引用的,那麼須要保證其生產的D.txt和R.txt和public.txt,其餘的module都須要持有(手動或者配置下載到其餘的module裏面),而後編譯的時候修改加入遍歷這些txt的資源文件。

4.重複觸發

我在一個插件module裏面發送一個信號,而後多個module都須要接受這些信號,那麼如何控制其它module接收順序,或者觸發順序調節呢?給個選擇題吧

(1)插件提供判斷參數給觸發插件,將觸發順序的邏輯都寫在觸發插件裏面。(這裏還須要考慮若是插件不存在的判空問題)

(2)將觸發的邏輯分發到其餘插件,而後經過插件獲取其餘插件的狀態(沒啓動或者不須要處理)而去判斷是否作相應的操做

這裏須要考慮到充分解耦的問題,由於代碼調整的觸發邏輯,控制很差咱們極可能須要更替一個或者多個module,就由於一個修改就更替module,這樣的設計是很是很差的。估計有人確定以爲這些方案都不適合吧。

那麼我就提供第三種方案吧。

(3)PluginManager在發送信號到其餘插件時候,在發送前作過濾操做,須要過濾什麼信號,就須要讀取一個列表過濾列表(經過包名過濾或者信號名過濾),作成服務器可配置,那麼隨時均可以轉換順序觸發邏輯了。

若是你看到這裏有更好的解耦方案,也能夠提出來,讓咱們繼續學習。

5.全局彈框

有人是否有想過Android的彈框(自定義Dialog)是怎麼彈出來的?

你想要在任意頁面裏面能夠彈出提示的彈框須要如何作?

咱們彈出彈框須要依賴於window,而且咱們建立dialog的時候須要頂層Activity的Content對象

那麼咱們須要如何能夠獲取到頂層的Activity的Content對象呢?

這裏面Application能夠提供該頂層Activity時候的聲明週期,做出回調,而後咱們能夠經過作成base

Module保存,其餘插件獲取context實現或者直接獲取彈框對象。(這裏面須要api level 14)



6.最重要的提醒

咱們最但願的是不能讓插件的任何調用會嵌入到宿主module或者其餘插件的module,任何通訊最好仍是經過底層base module作的通訊來協議來作,由於一旦木有判空,插件移除將會影響到宿主或者其餘插件崩潰。



這節就到這裏,但願對你們有必定的幫助。

若是你有更好的建議,請在評論中留言,我會和各位繼續相互討論,謝謝!

下一節將會更精彩!!!



我創建了一個關於Android架構學習的羣,裏面能夠進一步進行組件化學習和架構思想的的交流。

羣號是316556016,也能夠掃碼進羣。我在這裏期待大家的加入!!!

相關文章
相關標籤/搜索