手機做網(wǎng)站用什么軟件灰色詞排名推廣
組件化項目,通過gradle腳本,實現(xiàn)module在編譯期隔離,運行期按需加載,實現(xiàn)組件間解耦,高效單獨調(diào)試。
先來一張效果圖
組件化初衷
- APP版本不斷的迭代,新功能的不斷增加,業(yè)務也會變的越來越復雜,維護成本高。
- 業(yè)務耦合度高,代碼越來越臃腫,團隊內(nèi)部多人協(xié)作開發(fā)困難。
- Android項目在編譯代碼的時候電腦會非???#xff0c;又因為單一工程下代碼耦合嚴重,每修改一處代碼后都要重新編譯打包測試,導致非常耗時。
- 方便單元測試,改動單獨一個業(yè)務模塊,不需要著重于關(guān)注其他模塊被影響。
什么是組件化
組件化就是將一個app分成多個Module,如下圖,每個Module都是一個組件(也可以是一個基礎(chǔ)庫供組件依賴),開發(fā)的過程中我們可以單獨調(diào)試部分組件,組件間不需要互相依賴,但可以相互調(diào)用,最終發(fā)布的時候所有組件以lib的形式被主app工程依賴并打包成一個apk。
組件化優(yōu)勢
- 組件化就是將通用模塊獨立出來,統(tǒng)一管理,以提高復用,將頁面拆分為粒度更小的組件,組件內(nèi)部除了包含UI實現(xiàn),還包含數(shù)據(jù)層和邏輯層。
- 每個工程都可以獨立編譯、加快編譯速度,獨立打包。
- 每個工程內(nèi)部的修改,不會影響其他工程。
- 業(yè)務庫工程可以快速拆分出來,集成到其他App中。
- 迭代頻繁的業(yè)務模塊采用組件方式,業(yè)務線研發(fā)可以互不干擾、提升協(xié)作效率,并控制產(chǎn)品質(zhì)量,加強穩(wěn)定性。
- 并行開發(fā),團隊成員只關(guān)注自己的開發(fā)的小模塊,降低耦合性,后期維護方便等。
指導思想
- 組件拆分:將一個project劃分成業(yè)務組件、基礎(chǔ)組件、路由組件。其中業(yè)務組件是相互隔離的,可以單獨調(diào)試,基礎(chǔ)組件提供業(yè)務組件所公用的功能,路由組件為業(yè)務組件之間通信提供支持。
- 組件隔離:業(yè)務組件之間的隔離,可以單獨調(diào)試。
- 核心法則:編譯期隔離,運行期按需依賴。
依賴關(guān)系
組件化需要考慮的問題
- 模式切換:如何使得APP在單獨調(diào)試跟整體調(diào)試自由切換
- 資源沖突:當我們創(chuàng)建了多個Module的時候,如何解決相同資源文件名合并的沖突
- 依賴關(guān)系:多個Module之間如何引用一些共同的library以及工具類
- 組件通信:組件化之后,Module之間是相互隔離的,如何進行UI跳轉(zhuǎn)以及方法調(diào)用
- 入口參數(shù):我們知道組件之間是有聯(lián)系的,所以在單獨調(diào)試的時候如何拿到其它的Module傳遞過來的參數(shù)
組件化后項目結(jié)構(gòu)如下圖
理論說了那么多,下面開始擼代碼
實現(xiàn)步驟
1、全局設(shè)置Gradle,每一個業(yè)務Module需要的版本都定義在這里方便后期維護多個Module版本號
ext {// Sdk and toolsminSdkVersion = 16targetSdkVersion = 26compileSdkVersion = 26buildToolsVersion = '26.0.2'supportLibraryVersion = '26.1.0'// App dependenciesaRouter = '1.2.2'leakcanaryVersion = '1.3'glideVersion = '3.7.0'
}####每個業(yè)務Module編譯依賴版本compileSdkVersion rootProject.ext.compileSdkVersionbuildToolsVersion rootProject.ext.buildToolsVersionminSdkVersion rootProject.ext.minSdkVersiontargetSdkVersion rootProject.ext.targetSdkVersion
2、模式切換
組件化后的每一個業(yè)務的module都可以是一個單獨的APP(isModuleRun=false)
, release 包的時候各個業(yè)務module作為lib依賴,這里完全由一個變量控制,在根項目 gradle.properties
里面的 isModuleRun=true
。
isModuleRun狀態(tài)不同,加載application和AndroidManifest都不一樣,以此來區(qū)分是獨立的APK還是lib, 實現(xiàn)方式如下 在build.grade
里面配置
if (isModuleRun.toBoolean()) {apply plugin: 'com.android.application'
} else {apply plugin: 'com.android.library'
}##單Module運行需要配置
sourceSets {main {if (isModuleRun.toBoolean()) {manifest.srcFile 'src/main/debug/AndroidManifest.xml'} else {manifest.srcFile 'src/main/AndroidManifest.xml'java {//全部Module一起編譯的時候剔除debug目錄exclude '**/debug/**'}}}}
3、資源沖突
業(yè)務Module和BaseModule資源文件名稱重復會產(chǎn)生沖突,解決方案在 每個 module 都有 app_name,為了不讓資源名重名,在每個組件的 build.gradle 中增加 resourcePrefix “xxx_
強行檢查資源名稱前綴。 固定每個組件的資源前綴。但是 resourcePrefix 這個值只能限定 xml 里面的資源,并不能限定圖片資源。 個人認為約定大于配置,團隊內(nèi)協(xié)定好規(guī)范,可以避免沖突。
4、組件通訊 組件通訊框架在github上有star最多的有ARouter和ActivityArouter,前者是個人項目,后者是阿里巴巴開源,權(quán)衡之下選擇阿里的ARouter, 各業(yè)務Module之前不需要任何依賴可以通過路由跳轉(zhuǎn),完美解決業(yè)務之間耦合 使用方式如下。
if (BuildConfig.DEBUG) { // 這兩行必須寫在init之前,否則這些配置在init過程中將無效ARouter.openLog(); // 打印日志ARouter.openDebug(); // 開啟調(diào)試模式(如果在InstantRun模式下運行,必須開啟調(diào)試模式!線上版本需要關(guān)閉,否則有安全風險)}
ARouter.init(this); // 盡可能早,推薦在Application中初始化
compile "com.alibaba:arouter-api:$rootProject.aRouter"
每個業(yè)務Module都需要添加注解
annotationProcessor 'com.alibaba:arouter-compiler:1.1.3'
跳轉(zhuǎn)方法 在目標Activity上添加path
@Route(path = ARouterManager.BModuleActivity)
public class BModuleActivity extends BaseActivity {@Autowiredpublic String name;@Autowired(name = "age")int age;TextView txt;@Overrideprotected int getLayoutId() {return R.layout.b_module_layout;}@Overrideprotected void initView() {txt = findViewById(R.id.txt);//String name = getIntent().getStringExtra("name"); 也可以這樣接受參數(shù)ARouter.getInstance().inject(this);txt.setText("name:" + name + ",age:" + age);#開始跳轉(zhuǎn)btn2.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {// 2\. 跳轉(zhuǎn)并攜帶參數(shù)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文檔, ARouter
5、Application
當組件單獨運行的時候,每個Module自成一個APK,那么就意味著會有多個Application,很顯然我們不愿意重復寫這么多代碼,所以我們只需要定義一個BaseApplication即可,其它的Application直接繼承此BaseApplication就OK了,BaseApplication里面還可定義公用的參數(shù)。
更多Android進階指南 可以掃碼 解鎖 《Android十大板塊文檔》

1.Android車載應用開發(fā)系統(tǒng)學習指南(附項目實戰(zhàn))
2.Android Framework學習指南,助力成為系統(tǒng)級開發(fā)高手
3.2023最新Android中高級面試題匯總+解析,告別零offer
4.企業(yè)級Android音視頻開發(fā)學習路線+項目實戰(zhàn)(附源碼)
5.Android Jetpack從入門到精通,構(gòu)建高質(zhì)量UI界面
6.Flutter技術(shù)解析與實戰(zhàn),跨平臺首要之選
7.Kotlin從入門到實戰(zhàn),全方面提升架構(gòu)基礎(chǔ)
8.高級Android插件化與組件化(含實戰(zhàn)教程和源碼)
9.Android 性能優(yōu)化實戰(zhàn)+360°全方面性能調(diào)優(yōu)
10.Android零基礎(chǔ)入門到精通,高手進階之路
敲代碼不易,關(guān)注一下吧。?( ′・?・` ) 🤔