新建工程,首先來看一下工程結構
模塊化是一種思想:實現它的方式有組件化,插件化等等。(模塊化,多分包dex,熱修復,SPI(ARouter))關鍵詞
app是主工程,base是所有模塊都需要依賴,其他的屬於普通模塊,功能單一。這樣的結構比起傳統的工程結構更加高內聚低耦合。模塊之間的通信其實也可以採用EventBus來傳遞數據,需要回調數據的時候可以將xxEventBus定義成interface也是可以的。
EventBus的缺點:
1.一經發出所有的接收器都可以接受,功能較爲單一。
2.EventBus採用的是觀察者模式,在管理上非常不容易。當接收點過多的時候會讓人難以梳理邏輯。新人接手極爲不便。
3.非主工程的各個包之間的通信技術中如果採用EventBus,依然會導致包和包之間內聚。當EventBus激增後依然會導致項目混亂。
此時在後臺的技術中心抽取出了SPI技術,定義跨模塊通信,但是配置較爲複雜,不受大型企業的青睞。
ARouter中就爲我們解決了這個問題,相對成熟。
(此圖來自於瘋狂的程序員視頻中的截圖)
各個模塊需要提供服務怎麼做,在base公共模塊中定義服務的接口,然後由各個提供服務的模塊具體實現。其他的模塊需要調用服務的時候,通過調用公共base模塊,再去Router的配置服務表獲取即可。高內聚低耦合,模塊間完全獨立方便複用。因爲全部都是基於base的調用,模塊間不存在相互依賴。
接下來開始搬磚:
Project下的gradle(個人習慣 華爲的maven快一些喜歡拿走不謝)
buildscript { repositories { maven { url 'https://repo.huaweicloud.com/repository/maven/' } jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.6.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { maven { url 'https://repo.huaweicloud.com/repository/maven/' } jcenter() } } task clean(type: Delete) { delete rootProject.buildDir } ext{ //需檢查升級版本 arouterVersion = "1.2.2" arouterProcessorVersion = "1.1.3" }
接下來是關鍵各個模塊的gradle
首先說的是base
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.appcompat:appcompat:1.1.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' //ARouter api "com.alibaba:arouter-api:$rootProject.arouterVersion" }
根據官網別忘記加 javaCompileOptions
defaultConfig { minSdkVersion 21 targetSdkVersion 29 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles 'consumer-rules.pro' javaCompileOptions { annotationProcessorOptions { arguments = [ moduleName : project.getName() ] } } }
這裏說一下,注意這個moduleName 這個玩意兒和版本有關,新的版本用 AROUTER_MODULE_NAME代替,這裏也是哀鴻遍野。。
base這裏不需要”註解處理器“其他的獨立moudle都是需要的,這麼說吧,公共資源不需要,獨立的功能模塊都是需要的:
//ARouter 註解處理器 annotationProcessor "com.alibaba:arouter-compiler:$rootProject.arouterProcessorVersion"
annotationProcessor這個東西根據gradle的版本不一樣自己去查,寫法有一些差異。
implementation和api可以自己查詢使用方法,base因爲要通用,所以使用api然而implementation這個玩意兒在編譯的時候可以忽略。(多分包技術中心非常常用)
好了,接卸來看看 account-》gradle
defaultConfig { minSdkVersion 21 targetSdkVersion 29 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles 'consumer-rules.pro' javaCompileOptions { annotationProcessorOptions { arguments = [ moduleName : project.getName() ] } } }
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.appcompat:appcompat:1.1.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' api project(':base') //ARouter 註解處理器 annotationProcessor "com.alibaba:arouter-compiler:$rootProject.arouterProcessorVersion" }
task->gradle
defaultConfig { minSdkVersion 21 targetSdkVersion 29 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles 'consumer-rules.pro' javaCompileOptions { annotationProcessorOptions { arguments = [ moduleName : project.getName() ] } } }
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.appcompat:appcompat:1.1.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' api project(':base') //ARouter 註解處理器 annotationProcessor "com.alibaba:arouter-compiler:$rootProject.arouterProcessorVersion" }
配置到這裏也就結束了。接下來初始化一下ARouter
Application中的onCreate發放中
if(BuildConfig.DEBUG){ ARouter.openDebug(); } ARouter.init(this);
接下來在base模塊中註冊各個模塊的接口 IProvider
public interface AccountService extends IProvider { Account getAccount(); }
然後在account中實現這個接口
@Route(path = "/account/spi1") public class AccountServiceImpl implements AccountService { Context mContext; @Override public Account getAccount() { return AccountManager.getInstance().getAccount(); } @Override public void init(Context context) { mContext = context; } }
最後在task中調用
AccountService accountService = ARouter.getInstance().navigation(AccountService.class); Toast.makeText(this,"從用戶模塊獲取到用戶:"+accountService.getAccount().getName(), Toast.LENGTH_LONG).show();
坑1:手機OPPOR15 AccountService accountService = ARouter.getInstance().navigation(AccountService.class);獲取不到始終是null
解決辦法:卸載重新安裝,,,我也不知道爲毛!!!!!!!!!!!!!!!!!!!調了一個晚上。。。。。。只要重裝