模块通信模块间服务调用ARouter-IProvider
新建工程,首先来看一下工程结构
模块化是一种思想:实现它的方式有组件化,插件化等等。(模块化,多分包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
解决办法:卸载重新安装,,,我也不知道为毛!!!!!!!!!!!!!!!!!!!调了一个晚上。。。。。。只要重装