Android 组件化开发,ARouter 主要思想
ARouter 组件化开发【可重用,解耦】
基于可重用的目的,将应用拆分成多个独立组件,以减少解耦。
组件被其他组件依赖,可以单独成为独立的工程运行。
组件由担任负责,减少沟通成本。
组件 Component
模块化:按照功能拆分,分成相对独立的模块,模块可以包含多个组件。
组件化:更注重关注点分离。
组件化:每个模块最终打包,都是一个library,整个应用只有一个单独的apk;可重用,解耦,方便团队化开发。
插件化:拆分出多个apk, 在运行时通过动态加载的技术方案,来加载这些插件apk。频繁更新的功能,适合用插件化。
组件之间的通信,是使用路由实现的。
组件在 library 与 application 之间切换。
- 主工程:app的主入口启动页,初始化操作,配置信息添加。
- 主业务组件,建议使用【Phone & Tablet Module 需要再application/library之间切换】 创建Module
( ModuleName :modulesCore:main;
libraryName main;
) - 基础组件 【Android Library】:不需要切换到application 单独运行。
(ModuleName :modulesBase:libBase;) // 指定到文件夹中 - 功能组件 【Android Library】
(ModuleName :modulesPublic:modulePay;)
统一配置版本信息 根目录build.gradle
ext {
isDebug = false // 当为true,就是调试模式,组件可以单独运行;false,就是正式打包模式,此时是library。
android = [
compileSdkVersion:30,
minSdkVersion:28,
targetSdkVersion :30,
buildToolsVersion: "30.0.2",
versionCode:1,
versionName:"1.0"
]
applicationId = [ // 可以切换成application的 模块。
"app":"com.dongnaoedu.demo"
"main" :"com.dongnaoedu.module.main"
"login":"com.dongnaoedu.module.login"
]
// sdk中的公用库
library = [
"appcompat":"androidx.appcompaf:appcompat:1.1.0"
"material": "com.google.android.material:material:1.1.0"
"constraintlayout": "androidx.constraintlayout:constraintlayout:1.1.3"
]
// 第三方的
libARouter ="com.alibaba:arouter-api:1.5.1"
libARouterCompiler ="com.alibaba:arouter-compiler:1.5.1"
libGson ="com.google.code.gson:gson:2.8.6"
}
// mainModule 修改,可以在application与 library之间切换。
// build.gradle 使用全局配置的值,applicationId等。
def cfg = rootProject.ext
// 动态指定
if(cfg.isDebug){
apply plugin: 'com.android.application'
} else {
apply plugin: 'com.android.library'
}
android {
compileSdkVersion cfg.android.compileSdkVersion
buildToolsVersion cfg.android.buildToolsVersion
defaultConfig {
if(cfg.isDebug) { // 调试模式下,才是单独的application。
applicationId cfg.applicationId.main
}
minSdkVersion cfg.android.minSdkVersion
targetSdkVersion cfg.android.targetSdkVersion
versionCode cfg.android.versionCode
versionName cfg.android.versionName
}
}
// 处理公用依赖库
dependencies {
// api 可传递性的依赖。 libBase
// 不要往上传递的,使用 implementation
api project(':modulesBase:libBase')
}
settings.gradle
include ':modulesPublic:modulePay' // 文件夹下的 某个module
include ':modulesBase:libBase'
include ':modulesCore:main'
include ':app'
rootProject.name ="component demo"
libBase:: build.gradle
def cfg = rootProject.ext
apply plugin: 'com.android.library'
android {
compileSdkVersion cfg.android.compileSdkVersion
buildToolsVersion cfg.android.buildToolsVersion
defaultConfig {
minSdkVersion cfg.android.minSdkVersion
targetSdkVersion cfg.android.targetSdkVersion
versionCode cfg.android.versionCode
versionName cfg.android.versionName
}
}
// 处理公用依赖库, 防止重复依赖。使用api向上传递过去。
dependencies {
// api 可传递性的依赖。
api cfg.library.appcompat
api cfg.library.material
api cfg.library.constraintlayout
api cfg.libARouter // 添加Arouter
}
:modulesCore:login build.gradle
android {
defaultConfig {
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
}
}
dependencies {
annotationProcessor cfg.libARouterCompiler // 添加注解处理器,libARouter通过api传递过来。
}
给LoginActivity添加注解, groupName = login,
@Router(path = "/login/LoginActivity")
public class LoginActivity extends AppCompatActivity{}
app 主工程配置 build.gradle
def cfg = rootProject.ext
apply plugin: 'com.android.application'
android {
compileSdkVersion cfg.android.compileSdkVersion
buildToolsVersion cfg.android.buildToolsVersion
defaultConfig {
applicationId cfg.applicationId.app
minSdkVersion cfg.android.minSdkVersion
targetSdkVersion cfg.android.targetSdkVersion
versionCode cfg.android.versionCode
versionName cfg.android.versionName
}
}
// 处理公用依赖库
dependencies {
// api 可传递性的依赖。 libBase
// 不要往上传递的,使用 implementation
api project(':modulesBase:libBase')
implementation project(":moduleBase:libRouter")
if(!cfg.isDebug) {
implementation project(":moduleBase:main")
implementation project(":moduleBase:login")
}
}
特殊处理 modulesCore/main 的AndroidManifest.xml
在module 的src/main/debug 中,添加 AndroidManifest.xml 文件。
build.gradle 中添加。
android {
sourceSets {
main {
// 重新指定AndroidManifest 文件的路径。
if(cfg.isDebug) { // Debug模式,manifest下带 application 节点的详细信息。
manifest.srcFile 'src/main/debug/AndroidManifest.xml'
} else {
manifest.srcFile 'src/main/AndroidManifest.xml'
}
}
}
}
搭建组件化项目。
路由
多个组件之间通信---- 路由
主app, App--onCreate()
中注册。
Router.getInstance().register("/main/MainActivity", MainActivity.class);
Router.getInstance().register("/login/LoginActivity", LoginActivity.class);
LoginActivity 跳转到MainActivity
Router.getInstance().startActivity("/login/LoginActivity");
Router.getInstance().startActivity("/main/MainActivity");
ARoute的使用:
// ARouter 初始化操作
ARouter.init(this);
注册:通过注解
给LoginActivity添加注解, groupName = login,
@Router(path = "/login/LoginActivity")
public class LoginActivity extends AppCompatActivity{}
ARouter 跳转:
ARouter.getInstance().build("/login/LoginActivity").navigation();
ARouter.getInstance().build("/main/MainActivity").navigation();
跳转传参数:MainActivity
ARouter.getInstance().build("/login/LoginActivity")
.withLong("key1", 888L)
.withString("key2", "test")
.withSerializable("data", new User("Tom"))
.navigation(); // 发送出去。
加载传入的数据
@Router(path = "/login/LoginActivity")
public class LoginActivity extends AppCompatActivity {
// 处理ARouter 传递过来的数据
@Autowired
long key1; // 变量名= 前一个页面传递的key。
@Autowired(name = "key2")
String str; // 变量名称修改。
@Autowired
User data;
onCreate() {
ARouter.getInstance().inject(this); // 将对象,注入到 LoginActivity
Log.i("TAG", "key1= " + key1);
}
}
实现原理:通过path 找到class,然后做跳转 或拦截。
init()---> LogisticsCenter-- init()--
// 找到自动生成的类,都放到 routerMap 中。
routerMap = ClassUtils.getFileNameByPackageName(mContext, ROUTE_ROOT_PACKAGE);
---------------------END------------------------