说一千道一万不如亲自撸一遍,下面就直接新建项目,一步步搭建一个组件化架构的应用程序。下图为Demo项目整体架构:
简单做一下说明:
App模块为主模块,该模块不处理相关业务逻辑,只需将各个业务组件加以整合即可。另外需要说明的是,如果应用中使用了微信支付等相关SDK,要求相关回调类必须放置在主模块对应的包中,这时候就需要在app模块中添加相关逻辑处理了,不过最后通信一般都是用EventBus通知相关子模块。
中间层为相关业务模块,主要处理应用相关的业务逻辑
common层为公共模块,主要存放一些公共类库、公共资源等
app主模块依赖关系:
业务模块launcher依赖关系(其他业务模块一样):
common模块依赖关系(目前只依赖了Arouter和Glide):
上面介绍了项目整体架构以及相互依赖关系,下面需要添加一些公共配置供所有模块使用,以免每个模块重复添加相同的配置。
新建common_config.gradle文件
project.ext {
//1. APP全局配置变量
//2. debug 开关,切换全量编译和分模块编译开关
//3. app全局默认配置
//4. app业务模块配置
//5. lib全局默认配置
//6. lib业务模块配置
//7. dependencies公共依赖配置
}
“project”也可以省略,它相当于类中的“this”关键词。按照上面的说明一步步添加配置相关代码
第一步:App全局变量配置
app_compileSdkVersion = 29 //编译SDK版本
app_buildToolsVersion = "30.0.2" //buildTools版本
app_minSdkVersion = 21 //APP兼容最小版本号
app_targetSdkVersion = 29 //APP目标版本号,在该版本中充分测试
app_versionCode = 1 //APP版本号
app_versionName = '0.0.1' //APP版本名称
applicationId = '' //应用包名
prefix_applicationId = '' //appid前缀,debug模式下动态设置各个业务模块的appid
prefix_outputApkName = 'fanrenke-android-app-' //生成apk包名前缀,签名打包配置使用
//签名信息配置
keyAlias = ''
keyPassword = ''
storeFile = ''
storePassword = ''
第二步:debug 开关,切换全量编译和分模块编译开关
isDebug = false //debug模式开关
也可以单独为每一个模块设置一个开关分开控制,这里我设置了统一的开关,debug模式下所有的业务组件模块均可以独立编译运行。
第三步:app全局默认配置
//设置App默认配置,该配置不受isDebug状态影响
setAppDefaultConfig = {
extension ->
//引用Application插件库
extension.apply plugin: 'com.android.application'
extension.description 'app'
//配置android.defaultConfig相关属性
extension.android.defaultConfig {
applicationId prefix_applicationId + extension.getName()
}
//配置android及其子配置相关属性
extension.android setAndroidDefaultConfig
//配置相关公共依赖
extension.dependencies setDependencies
}
之所以不受debug状态影响关键在于extension.android setAndroidDefaultConfig属性,也就是setAndroidDefaultConfig这段代码块配置:
setAndroidDefaultConfig = {
compileSdkVersion app_compileSdkVersion
buildToolsVersion app_buildToolsVersion
defaultConfig {
minSdkVersion app_minSdkVersion
targetSdkVersion app_targetSdkVersion
versionCode app_versionCode
versionName app_versionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
//设置路由模块配置
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
}
这一段配置代码在下面步骤也会用到。
第四步:app业务模块配置
//设置APP全局默认配置,debug模式下各个模块分量编译
setAppConfig = {
extension ->
//引用Application插件库
extension.apply plugin: 'com.android.application'
extension.description 'app'
//配置android.defaultConfig相关属性
extension.android.defaultConfig {
applicationId prefix_applicationId + extension.getName()
}
//配置android及其子配置相关属性
extension.android setAndroidConfig
//配置相关公共依赖
extension.dependencies setDependencies
}
关键配置setAndroidConfig:
setAndroidConfig = {
compileSdkVersion app_compileSdkVersion
buildToolsVersion app_buildToolsVersion
defaultConfig {
minSdkVersion app_minSdkVersion
targetSdkVersion app_targetSdkVersion
versionCode app_versionCode
versionName app_versionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
//设置路由模块配置
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
}
//设置debug模式下各个模块配置文件路径
sourceSets {
main {
if (isDebug) {
manifest.srcFile 'src/main/module/AndroidManifest.xml'
} else {
manifest.srcFile 'src/main/AndroidManifest.xml'
//集成开发模式下排除debug文件夹中的所有java文件
java {
exclude 'debug/**'
}
}
}
}
}
主要区别在于添加了配置文件和debug模式下相关类的引用。
第五步:lib全局默认配置
//设置Lib全局默认配置,该配置不受isDebug状态影响
setLibDefaultConfig = {
extension ->
//添加library依赖
extension.apply plugin: 'com.android.library'
extension.description 'lib'
//配置android及其子配置相关属性
extension.android setAndroidDefaultConfig
//配置相关公共依赖
extension.dependencies setDependencies
}
关键配置setAndroidDefaultConfig在上面已经介绍。
第六步:lib业务模块配置
//设置Lib全局默认配置
setLibConfig = {
extension ->
//添加library依赖
extension.apply plugin: 'com.android.library'
extension.description 'lib'
//配置android及其子配置相关属性
extension.android setAndroidConfig
//配置相关公共依赖
extension.dependencies setDependencies
}
关键配置setAndroidConfig在上面已经介绍。
第七步:dependencies公共依赖配置
//设置依赖
setDependencies = {
//设置通用依赖
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
//设置路由依赖
annotationProcessor 'com.alibaba:arouter-compiler:1.2.1'
}
下面呈上全部配置代码:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
project.ext {
app_compileSdkVersion = 29
app_buildToolsVersion = "30.0.2"
app_minSdkVersion = 21
app_targetSdkVersion = 29
app_versionCode = 1 //APP版本号(可配置参数)
app_versionName = '0.0.1' //APP版本名称(可配置参数)
applicationId = 'com.allen.fanrenke' //应用包名(可配置参数)
prefix_applicationId = 'com.allen.' //可配置参数(可配置参数)
prefix_outputApkName = 'fanrenke-android-app-' //生成apk包名前缀(可配置参数)
//签名信息配置
keyAlias = ''
keyPassword = ''
storeFile = ''
storePassword = ''
//debug模式下可以分开编译模块
isDebug = false
/*------------------------分割线----------------------------*/
//设置App默认配置,该配置不受isDebug状态影响
setAppDefaultConfig = {
extension ->
//引用Application插件库
extension.apply plugin: 'com.android.application'
extension.description 'app'
//配置android.defaultConfig相关属性
extension.android.defaultConfig {
applicationId prefix_applicationId + extension.getName()
}
//配置android及其子配置相关属性
extension.android setAndroidDefaultConfig
//配置相关公共依赖
extension.dependencies setDependencies
}
/*--------------------分割线-----------------------*/
//设置APP全局默认配置,debug模式下各个模块分量编译
setAppConfig = {
extension ->
//引用Application插件库
extension.apply plugin: 'com.android.application'
extension.description 'app'
//配置android.defaultConfig相关属性
extension.android.defaultConfig {
applicationId prefix_applicationId + extension.getName()
}
//配置android及其子配置相关属性
extension.android setAndroidConfig
//配置相关公共依赖
extension.dependencies setDependencies
}
//设置Lib全局默认配置,该配置不受isDebug状态影响
setLibDefaultConfig = {
extension ->
//添加library依赖
extension.apply plugin: 'com.android.library'
extension.description 'lib'
//配置android及其子配置相关属性
extension.android setAndroidDefaultConfig
//配置相关公共依赖
extension.dependencies setDependencies
}
//设置Lib全局默认配置
setLibConfig = {
extension ->
//添加library依赖
extension.apply plugin: 'com.android.library'
extension.description 'lib'
//配置android及其子配置相关属性
extension.android setAndroidConfig
//配置相关公共依赖
extension.dependencies setDependencies
}
//设置Android配置,该配置不受isDebug状态影响
setAndroidDefaultConfig = {
compileSdkVersion app_compileSdkVersion
buildToolsVersion app_buildToolsVersion
defaultConfig {
minSdkVersion app_minSdkVersion
targetSdkVersion app_targetSdkVersion
versionCode app_versionCode
versionName app_versionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
//设置路由模块配置
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
}
}
//设置Android配置
setAndroidConfig = {
compileSdkVersion app_compileSdkVersion
buildToolsVersion app_buildToolsVersion
defaultConfig {
minSdkVersion app_minSdkVersion
targetSdkVersion app_targetSdkVersion
versionCode app_versionCode
versionName app_versionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
//设置路由模块配置
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
}
//设置debug模式下各个模块配置文件路径
sourceSets {
main {
if (isDebug) {
manifest.srcFile 'src/main/module/AndroidManifest.xml'
} else {
manifest.srcFile 'src/main/AndroidManifest.xml'
//集成开发模式下排除debug文件夹中的所有java文件
java {
exclude 'debug/**'
}
}
}
}
}
//设置依赖
setDependencies = {
//设置通用依赖
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
//设置路由依赖
annotationProcessor 'com.alibaba:arouter-compiler:1.2.1'
}
}
这里的模块主要指三种模块:
第一、需要一直参与编译的模块,如App模块
第二、debug模式下单独编译运行,release模式下以lib包形式被App依赖整体参与编译运行,如main等模块
第三、公共类库框架,这类模块不论debug模式还是release模式都要参与编译运行,如common模块以及其依赖的Glide、ARouter框架等。
下面将分开介绍这三种模块各自的配置方式。
App模块配置
引用common_config并添加相关配置
//引用common_config.gradle
apply from: "${rootProject.rootDir}/common_config.gradle"
//添加相关公共配置
project.ext.setAppDefaultConfig project
由于setAppDefaultConfig中已经有相关公共配置,因此android{}代码块中可以将相关公共通用配置删除,如下为android{}代码块全部内容:
android {
//配置签名信息
signingConfigs {
config {
keyAlias project.ext.keyAlias
keyPassword project.ext.keyPassword
storeFile file(project.ext.storeFile)
storePassword project.ext.storePassword
}
}
defaultConfig {
}
buildTypes {
release {
minifyEnabled true
zipAlignEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
//release模式下添加应用签名信息
signingConfig signingConfigs.config
}
debug {
//debug模式下添加应用签名信息,兼容相关第三方SDK需要签名才能进行操作的问题
signingConfig signingConfigs.config
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
//输出apk
applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = project.ext.prefix_outputApkName + "${variant.versionName}-${buildTime()}.apk"
}
}
}
static def buildTime() {
def df = new SimpleDateFormat("yyyyMMddHHmmss")
df.setTimeZone(TimeZone.getDefault())
return df.format(new Date())
}
dependencies依赖配置:
dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
if (project.ext.isDebug) { //debug状态下分量编译
implementation project(':commonlib')
} else {
api project(':launcher')
api project(':main')
api project(':find')
api project(':mine')
}
}
呈上全部配置代码:
import java.text.SimpleDateFormat
apply from: "${rootProject.rootDir}/common_config.gradle"
project.ext.setAppDefaultConfig project
android {
//配置签名信息
signingConfigs {
config {
keyAlias project.ext.keyAlias
keyPassword project.ext.keyPassword
storeFile file(project.ext.storeFile)
storePassword project.ext.storePassword
}
}
defaultConfig {
}
buildTypes {
release {
minifyEnabled true
zipAlignEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
//release模式下添加应用签名信息
signingConfig signingConfigs.config
}
debug {
//debug模式下添加应用签名信息,兼容相关第三方SDK需要签名才能进行操作的问题
signingConfig signingConfigs.config
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
//输出apk
applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = project.ext.prefix_outputApkName + "${variant.versionName}-${buildTime()}.apk"
}
}
}
static def buildTime() {
def df = new SimpleDateFormat("yyyyMMddHHmmss")
df.setTimeZone(TimeZone.getDefault())
return df.format(new Date())
}
dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
if (project.ext.isDebug) { //debug状态下分量编译
implementation project(':commonlib')
} else {
api project(':launcher')
api project(':main')
api project(':find')
api project(':mine')
}
}
main模块配置
直接呈上全部配置代码,这里主要讲讲相关配置文件以及debug状态下相关类的创建。
apply from: "${rootProject.rootDir}/common_config.gradle"
if (project.ext.isDebug) {
project.ext.setAppConfig project
} else {
project.ext.setLibConfig project
}
android {
defaultConfig {
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
api project(':commonlib')
}
新建debug模式下相关配置文件:
在main模块main文件夹下新建module文件件,新建AndroidManifest.xml工程配置文件;在main/java文件夹下新建debug包,添加MainApp类,作为debug模式下main模块的程序入口。这里就牵涉到common_config中的相关配置代码:
//设置debug模式下各个模块配置文件路径
sourceSets {
main {
if (isDebug) {
manifest.srcFile 'src/main/module/AndroidManifest.xml'
} else {
manifest.srcFile 'src/main/AndroidManifest.xml'
//集成开发模式下排除debug文件夹中的所有java文件
java {
exclude 'debug/**'
}
}
}
}
上面的配置说明debug模式下配置文件取src/main/module路径下的AndroidManifest.xml,否则取src/main路径下的AndroidManifest.xml。release模式下debug包中的相关类不参与编译打包。测试一下。
release模式下:
可见其他业务组件模块不能直接单独编译,配置文件取的是src/main路径下的AndroidManifest.xml。
debug模式下:
可见其他业务组件模块都可以单独参与编译,配置文件取的是src/main/module路径下的AndroidManifest.xml。
common模块配置
直接上代码:
apply from: "${rootProject.rootDir}/common_config.gradle"
project.ext.setLibDefaultConfig project
android {
defaultConfig {
versionCode project.ext.app_versionCode
versionName project.ext.app_versionName
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
api 'com.alibaba:arouter-api:1.4.0'
api 'com.github.bumptech.glide:glide:4.11.0'
}
没啥讲的,就是引用common_config.gradle,删除公共配置,添加独有配置
上一节对组件化的相关配置做了详细地介绍,但实际上按照先前的方法去搭建组件化架构是有一些漏洞的,主要体现在两个方面:
第一、debug模式下app模块如果也能直接编译运行,由于此时app模块已经脱离依赖其他业务组件,就会导致在app模块中相关类找不到,这样一来app模块就无法编译运行了
第二、业务组件中,如果入口为Activity还好说,但是如果模块入口就是一个Fragment该怎么办,这样debug模式下业务组件该如何单独运行调试
可能还存在其他问题,以后慢慢发掘。现针对上面两个问题加以分析处理。
app模块处理方式
这里大体有两种处理方式:
① debug模式下禁止app模块单独编译运行
这种处理方式类似于debug模式下将app模块以lib包形式处理,具体实现方式如下:
import java.text.SimpleDateFormat
apply from: "${rootProject.rootDir}/common_config.gradle"
//注释1
if (project.ext.isDebug) { //debug状态下不能运行
project.ext.setLibDefaultConfig project
} else {
project.ext.setAppDefaultConfig project
}
android {
//配置签名信息
signingConfigs {
config {
keyAlias project.ext.keyAlias
keyPassword project.ext.keyPassword
storeFile file(project.ext.storeFile)
storePassword project.ext.storePassword
}
}
defaultConfig {
}
buildTypes {
release {
minifyEnabled true
zipAlignEnabled true
//注释2
//一些属性debug模式下是不能使用的
if (!project.ext.isDebug) {
shrinkResources true
}
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
//release模式下添加应用签名信息
signingConfig signingConfigs.config
}
debug {
//debug模式下添加应用签名信息,兼容相关第三方SDK需要签名才能进行操作的问题
signingConfig signingConfigs.config
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
//注释3
//debug模式下不能输出apk
if (!project.ext.isDebug) {
applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = project.ext.prefix_outputApkName + "${variant.versionName}-${buildTime()}.apk"
}
}
}
}
static def buildTime() {
def df = new SimpleDateFormat("yyyyMMddHHmmss")
df.setTimeZone(TimeZone.getDefault())
return df.format(new Date())
}
dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
if (project.ext.isDebug) { //debug状态下分量编译
implementation project(':commonlib')
} else {
api project(':launcher')
api project(':main')
api project(':find')
api project(':mine')
}
}
分别注意一下上面代码中注释1,2,3处与先前有什么不同。
经此方式处理之后,release模式下:
debug模式下:
这样就做到了debug模式下无法对app模块单独编译处理,从而解决了上面的问题
② debug模式下为app模块单独创建一个壳子Activity
这种处理方式类似业务组件的处理,相当于也把app模块当成了业务组件,但我个人不是很喜欢这种处理方式,明知是个壳,就算运行了也看不到相关业务板块,但这里还是简单介绍一下。
先呈上app.gradle配置源码:
import java.text.SimpleDateFormat
apply from: "${rootProject.rootDir}/common_config.gradle"
//注释1
if (project.ext.isDebug) {
project.ext.setAppConfig project
} else {
project.ext.setAppDefaultConfig project
}
android {
//配置签名信息
signingConfigs {
config {
keyAlias project.ext.keyAlias
keyPassword project.ext.keyPassword
storeFile file(project.ext.storeFile)
storePassword project.ext.storePassword
}
}
defaultConfig {
}
buildTypes {
release {
minifyEnabled true
zipAlignEnabled true
//注释2
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
//release模式下添加应用签名信息
signingConfig signingConfigs.config
}
debug {
//debug模式下添加应用签名信息,兼容相关第三方SDK需要签名才能进行操作的问题
signingConfig signingConfigs.config
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
//注释3
//输出apk
applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = project.ext.prefix_outputApkName + "${variant.versionName}-${buildTime()}.apk"
}
}
}
static def buildTime() {
def df = new SimpleDateFormat("yyyyMMddHHmmss")
df.setTimeZone(TimeZone.getDefault())
return df.format(new Date())
}
dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
if (project.ext.isDebug) { //debug状态下分量编译
implementation project(':commonlib')
} else {
api project(':launcher')
api project(':main')
api project(':find')
api project(':mine')
}
}
注意注释1,2,3处与上一种方法有什么不同之处,注释1处用setAppConfig替换了setLibDefaultConfig,等于说还是把app模块当成可编译运行的模块而不是一个lib包。
common_config.gradle中的变动:
setAndroidDefaultConfig = {
compileSdkVersion app_compileSdkVersion
buildToolsVersion app_buildToolsVersion
defaultConfig {
minSdkVersion app_minSdkVersion
targetSdkVersion app_targetSdkVersion
versionCode app_versionCode
versionName app_versionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
//设置路由模块配置
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
}
//注释1
//release模式下还原资源路径
sourceSets {
main {
manifest.srcFile 'src/main/AndroidManifest.xml'
//集成开发模式下排除debug文件夹中的所有java文件
java {
exclude 'debug/**'
}
}
}
}
注释1处的作用是使app模块在release模式下还原资源加载路径。
另一方面,还需要再在app模块中添加相关文件,如图:
这时,app模块是可以单独编译运行的,只不过此时加载的页面是AppIndexActActivity而不是MainActivity,同时配置文件取的也是module包中的。
release模式下:
此时,APP整体可以正常整体编译运行,入口界面是MainActivity,配置文件取的是src/main文件夹中的。
业务组件模块处理方式
入口为Activity的话无需多说,直接在module中配置文件添加对应Activity并设置action和category,至于如何做到与其他组件之间的通信,在下一节再做研究。这里主要研究一下业务模块入口为Fragment的情况。
Fragment必须依托于Activity才能存在,因此可以在debug包下新建一个入口Activity,然后在入口Activity中实现对应Fragment的加载。这里入口Activity中除了添加Fragment的逻辑之外不再处理其他相关业务逻辑,而Fragment中相关业务操作也可以通过接口与其他模块通信,具体实现在下一节详述。
这里分为release模式下和debug模式下的通信,debug模式下每一个业务组件都有各自独立的进程,因此在debug模式下组件之间的通信需要用到进程间通信实现方式,这个知识点会单独在Android IPC机制中介绍。但这种通信有一个前提,就是A组件想要调用B组件中的方法,需要A、B组件都处于运行状态,即进程存活状态,否则就算使用AIDL也无法实现组件之间的通信。
因此我们主要讲一下release模式下组件之间通信的实现方式。
第一步、在入口Application中初始化ARouter
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
//ARouter设置
if (BuildConfig.DEBUG) {
ARouter.openLog();
ARouter.openDebug();
}
ARouter.init(this);
}
}
这里最终实现app模块和find模块调用main模块中的方法,然后给出一个Toast提示。
第二步、commonlib模块中添加find对外服务接口
/**
* @Description: main模块对外提供的服务接口
* @Author: Allen
* @CreateDate: 2020-11-20 16:55
* @Version: 1.0
*/
public interface MainExportService extends IProvider {
//注释1
String sayHello(String s);
}
注释1处定义了一个方法供其他组件调用。
第三步、main模块中添加MainExportService的实现类,实现具体操作
/**
* @Description: main模块对外提供服务的实现类
* @Author: Allen
* @CreateDate: 2020-11-20 16:57
* @Version: 1.0
*/
//注释1
@Route(path = RouterConstants.MAIN_SERVICE)
public class MainService implements MainExportService {
@Override
public String sayHello(String s) {
return "我是来自main模块的问候:" + s;
}
@Override
public void init(Context context) {
}
}
注释1处为MainService指定了Router路由,供其他组件通过ARouter调用。
第四步、在其他组件中添加具体调用
app模块中在MainActivity中调用:
public class MainActivity extends AppCompatActivity {
//通过ARouter获取MainExportService实例
@Autowired(name = RouterConstants.MAIN_SERVICE)
public MainExportService mainExportService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//依赖注入该页面
ARouter.getInstance().inject(this);
}
//页面按钮点击事件
public void testComm(View view) {
if (mainExportService != null) {
Toast.makeText(this, mainExportService.sayHello("你好!"), Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "mainExportService为空", Toast.LENGTH_SHORT).show();
}
}
//跳转到find模块中再次测试find与main之间的通信
public void goFind(View view) {
ARouter.getInstance()
.build(RouterConstants.FIND_TEST)
.navigation();
}
}
上面注释的很清晰,需要在MainActivity中将ARouter进行依赖注入,然后通过@Autowired获取到MainExportService的实例,最后在点击事件中调用。至于find模块中的具体实现与MainActivity中一样,这里不多做介绍。