Android 組件化方案探索與思考
03-22
Android 組件化方案探索與思考
組件化項目,通過gradle腳本,實現module在編譯期隔離,運行期按需載入,實現組件間解耦,高效單獨調試。
本項目github地址https://github.com/wang709693972wei/CompontentDemo先來一張效果圖,建議讀者clone項目後跟著項目看這篇文章,有任何不明白的地方可留言或者聯繫我,我看到後會立刻回復你。
- APP版本不斷的迭代,新功能的不斷增加,業務也會變的越來越複雜,維護成本高。
- 業務耦合度高,代碼越來越臃腫,團隊內部多人協作開發困難。
- Android項目在編譯代碼的時候電腦會非常卡,又因為單一工程下代碼耦合嚴重,每修改一處代碼後都要重新編譯打包測試,導致非常耗時。
- 方便單元測試,改動單獨一個業務模塊,不需要著重於關注其他模塊被影響。
什麼是組件化
組件化就是將一個app分成多個Module,如下圖,每個Module都是一個組件(也可以是一個基礎庫供組件依賴),開發的過程中我們可以單獨調試部分組件,組件間不需要互相依賴,但可以相互調用,最終發布的時候所有組件以lib的形式被主app工程依賴並打包成一個apk。
組件化優勢
- 組件化就是將通用模塊獨立出來,統一管理,以提高復用,將頁面拆分為粒度更小的組件,組件內部除了包含UI實現,還包含數據層和邏輯層。
- 每個工程都可以獨立編譯、加快編譯速度,獨立打包。
- 每個工程內部的修改,不會影響其他工程。
- 業務庫工程可以快速拆分出來,集成到其他App中。
- 迭代頻繁的業務模塊採用組件方式,業務線研發可以互不干擾、提升協作效率,並控制產品質量,加強穩定性。
- 並行開發,團隊成員只關注自己的開發的小模塊,降低耦合性,後期維護方便等。
指導思想
- 組件拆分:將一個project劃分成業務組件、基礎組件、路由組件。其中業務組件是相互隔離的,可以單獨調試,基礎組件提供業務組件所公用的功能,路由組件為業務組件之間通信提供支持。
- 組件隔離:業務組件之間的隔離,可以單獨調試。
- 核心法則:編譯期隔離,運行期按需依賴。
依賴關係
- 模式切換:如何使得APP在單獨調試跟整體調試自由切換
- 資源衝突:當我們創建了多個Module的時候,如何解決相同資源文件名合併的衝突
- 依賴關係:多個Module之間如何引用一些共同的library以及工具類
- 組件通信:組件化之後,Module之間是相互隔離的,如何進行UI跳轉以及方法調用
- 入口參數:我們知道組件之間是有聯繫的,所以在單獨調試的時候如何拿到其它的Module傳遞過來的參數
組件化後項目結構如下圖
理論說了那麼多,下面開始擼代碼實現步驟1、全局設置Gradle ,每一個業務Module需要的版本都定義在這裡方便後期維護多個Module版本號ext { // Sdk and tools
minSdkVersion = 16
targetSdkVersion = 26 compileSdkVersion = 26 buildToolsVersion = 26.0.2 supportLibraryVersion = 26.1.0 // App dependencies aRouter = 1.2.2 leakcanaryVersion = 1.3 glideVersion = 3.7.0}####每個業務Module編譯依賴版本
compileSdkVersion rootProject.ext.compileSdkVersion buildToolsVersion rootProject.ext.buildToolsVersion minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion2、模式切換組件化後的每一個業務的module都可以是一個單獨的APP(isModuleRun=false), release 包的時候各個業務module作為lib依賴,這裡完全由一個變數控制,在根項目 gradle.properties裡面的 isModuleRun=true。isModuleRun狀態不同,載入application和AndroidManifest都不一樣,以此來區分是獨立的APK還是lib,實現方式如下在build.grade裡面配置
manifest.srcFile src/main/debug/AndroidManifest.xml
} else { manifest.srcFile src/main/AndroidManifest.xml java { //全部Module一起編譯的時候剔除debug目錄 exclude **/debug/** } } } }各業務Module之前不需要任何依賴可以通過路由跳轉,完美解決業務之間耦合
使用方式如下。if (BuildConfig.DEBUG) { // 這兩行必須寫在init之前,否則這些配置在init過程中將無效 ARouter.openLog(); // 列印日誌 ARouter.openDebug(); // 開啟調試模式(如果在InstantRun模式下運行,必須開啟調試模式!線上版本需要關閉,否則有安全風險) }ARouter.init(this); // 儘可能早,推薦在Application中初始化compile "com.alibaba:arouter-api:$rootProject.aRouter"每個業務Module都需要添加註解annotationProcessor com.alibaba:arouter-compiler:1.1.3
跳轉方法在目標Activity上添加path@Route(path = ARouterManager.BModuleActivity)public class BModuleActivity extends BaseActivity { @Autowired public String name; @Autowired(name = "age") int age; TextView txt; @Override protected int getLayoutId() { return R.layout.b_module_layout; } @Override protected void initView() { txt = findViewById(R.id.txt); //String name = getIntent().getStringExtra("name"); 也可以這樣接受參數 ARouter.getInstance().inject(this); txt.setText("name:" + name + ",age:" + age); #開始跳轉 btn2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // 2. 跳轉並攜帶參數 ARouter.getInstance().build(ARouterManager.BModuleActivity) .withString("name", "888") .withInt("age", 11) .navigation(); } });/** * 路由管理類 */public final class ARouterManager { public static final String AFragment = "/amodule/AFragment"; public static final String BFragment = "/bmodule/BFragment"; public static final String CFragment = "/cmodule/CFragment"; public static final String AModuleActivity = "/amodule/AAModuleActivity"; public static final String BModuleActivity = "/bmodule/BModuleActivity"; public static final String CModuleActivity = "/cmodule/CModuleActivity";}上述只使用了ARouter的簡單用法,更多進階用法請參考ARouter文檔,ARouter5、Application當組件單獨運行的時候,每個Module自成一個APK,那麼就意味著會有多個Application,很顯然我們不願意重複寫這麼多代碼,所以我們只需要定義一個BaseApplication即可,其它的Application直接繼承此BaseApplication就OK了,BaseApplication裡面還可定義公用的參數。鏈接:https://www.jianshu.com/p/010d946e8f67,轉載請註明原創微信公眾號:終端研發部http://weixin.qq.com/r/JzgHH6PEpv7Zred89201 (二維碼自動識別)
推薦閱讀:
TAG:Android工程師 | iOS | Android |
