Android 组件化实战,kotlin 协程实现原理
if (isApplicationModule1.toBoolean()){
apply plugin: 'com.android.application'
}else{
apply plugin: 'com.android.library'
}
(2) 增加 applicationId
defaultConfig {
if (isApplicationModule1.toBoolean()){
applicationId "com.demo.myapplication.module1"
}
}
(3) AndroidManifest 启动入口
sourceSets {
main {
if (isApplicationModule1.toBoolean()) {
manifest.srcFile 'src/main/module/AndroidManifest.xml'
} else {
manifest.srcFile 'src/main/AndroidManifest.xml'
}
}
}
4. 在主 app module 中引入其他 Module
要注意的一点是每个组件如果是独立运行的话,那它是不能作为依赖库供 app 模块使用的,所以在 app 模块下的 build.gradle 文件中需要进行依赖判断
if (!isApplicationModule1.toBoolean()){
implementation project(':module1')
}
if (!isApplicationModule2.toBoolean()){
implementation project(':module2')
}
if (!isApplicationModule3.toBoolean()){
implementation project(':module3')
}
implementation project(':common')
在模块 Module 中引入 common module
implementation project(':common')
至此通过修改配置,每个 Module 就可以单独运行。
5. 引入 Arouter
由于需要模块之间的解耦,平时的 Intent 跳转需要导包,而 Arouter 引入之后,就能在跳转的同时不用导包。
集成 Arouter
(1) 引入依赖
common 中添加
api("com.alibaba:arouter-api:$rootProject.ext.arouterLibVersion") { exclude group: 'com.android.support' }
annotationProcessor "com.alibaba:arouter-compiler:$rootProject.ext.arouterAnnotationLibVersion"
在每个 Module 下都需要添加注解
annotationProcessor "com.alibaba:arouter-compiler:$rootProject.ext.arouterAnnotationLibVersion"
(2) 每个引入 Arouter 的 Module 的 build.gradle 中加入下面代码
defaultConfig {
...
//arouter
javaCompileOptions {
annotationProcessorOptions {
arguments = [moduleName: project.getName()]
}
}
}
(3) 在 Application 中进行初始化
if (isDebug) {
ARouter.openLog();
ARouter.openDebug();
}
ARouter.init(this);
(4)使用 Arouter 跳转
定义路由
@Route(path = "/app/main")
public class MainActivity extends AppCompatActivity {
...
}
跳转路由
ARouter.getInstance().build("/app/main").navigation();
6. ButterKnife 的坑
单工程使用这个库是没有问题的,但是在组件化使用的时候就报错了。 除了一系列的配置之外,还有个难受的地方就是需要把 Library 中的 R 改成 R2,但当你想把 Library 改成 Application 时,又要将 R2 改成 R,这岂不是很难受。
!!! 所以我目前放弃在 Library 中使用 ButterKnife
7. switch (view.getId()) 的坑
由于 Library 中的 view.getId 可能是个变量,所以需要把 switch 改成 if。
快捷操作:
光标移至 switch 这行代码上,同时按下 alt + Enter, 此时点击 Replace switch to if
8. 资源重复的坑
No static field XXX of type I in class Lcom/XXX/R$id 错误
出现这个问题是 layout 和 主布局名字重复了,养成习惯,在 Library 中资源文件前加上标识,比如 library_layout
另外有一种方法只是帮忙增加约束,提醒。
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
// 增加资源的约束,提醒
if (toolsIsLibrary.toBoolean()) {
resourcePrefix "${project.name}_"
}
}
为了保证不与其他 module 冲突,建议在 string、style、color、dimens 等资源文件都加上前缀。
六、踩坑
1. ARouter 组件化打包不成功
出现问题:Program type already present: com.alibaba.android.arouter.routes.ARouterGroupGroupservice
在 ModuleA 和 ModuleB 中不能使用相同的 Group。
根据提示报错 service 就是重复的 Group,全局搜索,于是发现在 ModuleA 和 ModuleB 中都存在以下代码。
package com.bp.tech.common.util;
import android.content.Context;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.facade.service.SerializationService;
import java.lang.reflect.Type;
@Route(path = "/service/json")
public class JsonServiceImpl implements SerializationService {
@Override
public void init(Context context) {
}
@Override
public <T> T json2Object(String text, Class<T> clazz) {
return GsonUtils.parseObject(text, clazz);
}
@Override
public String object2Json(Object instance) {
return GsonUtils.toJsonString(instance);
}
@Override
public <T> T parseObject(String input, Type clazz) {
return GsonUtils.parseObject(input, clazz);
评论