热门技术终端研发部组件化之路

Android 组件化方案探索与思考

2018-04-27  本文已影响1160人  wayDevelop

组件化项目,通过gradle脚本,实现module在编译期隔离,运行期按需加载,实现组件间解耦,高效单独调试。

本项目github地址

https://github.com/wang709693972wei/CompontentDemo
先来一张效果图,建议读者clone项目后跟着项目看这篇文章,有任何不明白的地方可留言或者联系我,我看到后会立刻回复你。

组件化初衷

什么是组件化

组件化就是将一个app分成多个Module,如下图,每个Module都是一个组件(也可以是一个基础库供组件依赖),开发的过程中我们可以单独调试部分组件,组件间不需要互相依赖,但可以相互调用,最终发布的时候所有组件以lib的形式被主app工程依赖并打包成一个apk。


组件化优势

指导思想

依赖关系

组件化需要考虑的问题

组件化后项目结构如下图


理论说了那么多,下面开始撸代码


实现步骤

1、全局设置Gradle ,每一个业务Module需要的版本都定义在这里方便后期维护多个Module版本号

ext {
    // Sdk and tools
    minSdkVersion = 16
    targetSdkVersion = 26
    compileSdkVersion = 26
    buildToolsVersion = '26.0.2'
    supportLibraryVersion = '26.1.0'

    // App dependencies
    aRouter = '1.2.2'
    leakcanaryVersion = '1.3'
    glideVersion = '3.7.0'
}

 ####每个业务Module编译依赖版本
 compileSdkVersion rootProject.ext.compileSdkVersion
 buildToolsVersion rootProject.ext.buildToolsVersion
 minSdkVersion rootProject.ext.minSdkVersion
 targetSdkVersion rootProject.ext.targetSdkVersion

2、模式切换

组件化后的每一个业务的module都可以是一个单独的APP(isModuleRun=false), release 包的时候各个业务module作为lib依赖,这里完全由一个变量控制,在根项目 gradle.properties里面的 isModuleRun=true

isModuleRun状态不同,加载application和AndroidManifest都不一样,以此来区分是独立的APK还是lib,
实现方式如下
build.grade里面配置

if (isModuleRun.toBoolean()) {
    apply plugin: 'com.android.application'
} else {
    apply plugin: 'com.android.library'
}

##单Module运行需要配置
sourceSets {
        main {
            if (isModuleRun.toBoolean()) {
                manifest.srcFile 'src/main/debug/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/AndroidManifest.xml'
                java {
                    //全部Module一起编译的时候剔除debug目录
                    exclude '**/debug/**'
                }
            }
        }
    }

3、资源冲突

业务Module和BaseModule资源文件名称重复会产生冲突,解决方案在
每个 module 都有 app_name,为了不让资源名重名,在每个组件的 build.gradle 中增加 resourcePrefix “xxx_强行检查资源名称前缀。
固定每个组件的资源前缀。但是 resourcePrefix 这个值只能限定 xml 里面的资源,并不能限定图片资源。
个人认为约定大于配置,团队内协定好规范,可以避免冲突。

4、组件通讯
不熟悉ARouter基本用法的可以看看我的这篇文章
阿里巴巴ARouter基本使用方法

组件通讯框架在github上有star最多的有ARouter和ActivityArouter,前者是个人项目,后者是阿里巴巴开源,权衡之下选择阿里的ARouter,
各业务Module之前不需要任何依赖可以通过路由跳转,完美解决业务之间耦合
使用方式如下。

 if (BuildConfig.DEBUG) {   // 这两行必须写在init之前,否则这些配置在init过程中将无效
           ARouter.openLog();     // 打印日志
           ARouter.openDebug();   // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)
        }
ARouter.init(this); // 尽可能早,推荐在Application中初始化
compile "com.alibaba:arouter-api:$rootProject.aRouter"
每个业务Module都需要添加注解
annotationProcessor 'com.alibaba:arouter-compiler:1.1.3'

跳转方法
在目标Activity上添加path

@Route(path = ARouterManager.BModuleActivity)
public class BModuleActivity extends BaseActivity {
    @Autowired
    public String name;
    @Autowired(name = "age")
    int age;
    TextView txt;

    @Override
    protected int getLayoutId() {
        return R.layout.b_module_layout;
    }

    @Override
    protected void initView() {
        txt = findViewById(R.id.txt);
        //String name = getIntent().getStringExtra("name"); 也可以这样接受参数
        ARouter.getInstance().inject(this);
        txt.setText("name:" + name + ",age:" + age);


  #开始跳转
 btn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 2. 跳转并携带参数
                ARouter.getInstance().build(ARouterManager.BModuleActivity)
                        .withString("name", "888")
                        .withInt("age", 11)
                        .navigation();
            }
        });
/**
 * 路由管理类
 */

public final class ARouterManager {


    public static final String AFragment = "/amodule/AFragment";
    public static final String BFragment = "/bmodule/BFragment";
    public static final String CFragment = "/cmodule/CFragment";

    public static final String AModuleActivity = "/amodule/AAModuleActivity";
    public static final String BModuleActivity = "/bmodule/BModuleActivity";
    public static final String CModuleActivity = "/cmodule/CModuleActivity";

}

上述只使用了ARouter的简单用法,更多进阶用法请参考ARouter文档,
ARouter

5、Application

当组件单独运行的时候,每个Module自成一个APK,那么就意味着会有多个Application,很显然我们不愿意重复写这么多代码,所以我们只需要定义一个BaseApplication即可,其它的Application直接继承此BaseApplication就OK了,BaseApplication里面还可定义公用的参数。

如果你觉得本文对你有帮助,请分享给更多的人 关注【Android杂货店】,每天都有Android 干货文章分享!
上一篇下一篇

猜你喜欢

热点阅读