Android 组件化实践

项目地址:https://github.com/xiongliang120/ComponentPratice

组件化结构图

组件化实施流程
      组件模式和集成模式的转换
      组件AndroidMainfest.xml 合并的问题
      动态配置Applicaiton
      组件引入library 冲突问题
      组件间通信,集成Arouter
      组件资源名冲突
      组件化混淆
      build.gradle 和 gradle.properties 版本参数优化

1:组件模式和集成模式的转换

2:组件AndroidMainfest.xml 合并

在集成模式下,组件和App壳工程的AndroidMainfest.xml 的 android:name, android:label 冲突时,可以在壳工程配置 tools:replace="android:label,android:name"解决冲突。

3:动态配置Application

组件功能模块需要做一些初始化操作,只能强引用壳工程的Applicaiton,能不能做到解耦?
通过壳工程的Application继承Base module的Application来实现,主module的Application将注册每个module的初始化文件,然后通过Base module中的Applicaiton 来对初始化文件做启动封装。

(1)在Base module中声明初始化类

public class BaseAppLogic {
    public BaseAppLogic(){}
    public void onCreate(){}
    public void onTerminate(){}
    public void onLowMemory(){}
    public void onTrimMemory(int level){}
    public void onConfigurationChanged(Configuration newConfig){}
}

(2)在Base module中添加Application的注册和运行逻辑

public abstract class BaseApplication extends Application {
    private List<Class<? extends BaseAppLogic>> logicList = new ArrayList<>();
    private List<BaseAppLogic> logicClassList = new ArrayList<>();
    @Override
    public void onCreate() {
        super.onCreate();
        boolean isDebugModel = BuildConfig.MODE_MARKET ? false : BuildConfig.MODE_DEBUG;
        boolean isLogModel = BuildConfig.MODE_MARKET ? false : BuildConfig.MODE_LOGGER;

        AppCore.init(this,isDebugModel);
        AppCore.enableLogger(isLogModel);
        initLogic();
        logicCreate();
    }
    protected abstract void initLogic();
    public void registerApplicationLogin(Class<? extends BaseAppLogic> logicClass){
        logicList.add(logicClass);
    }
    private void logicCreate(){
        for (Class<? extends BaseAppLogic> logicClass : logicList){
            try{
                BaseAppLogic appLogic = logicClass.newInstance();
                logicClassList.add(appLogic);
                appLogic.onCreate();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
    @Override
    public void onTerminate() {
        super.onTerminate();
        for(BaseAppLogic appLogic:logicClassList){
            appLogic.onTerminate();
        }
    }
}

(3)每个module需要初始化时继承此类,然后覆写需要的接口

public class ArticleInitLogic extends BaseAppLogic {
    @Override
    public void onCreate() {
        super.onCreate();
    }
    @Override
    public void onTerminate() {
        super.onTerminate();
    }
} 

(4)主module的Application调用initLogic 注册所有的BaseAppLogic类

public class ComponentApplication extends BaseApplication {
    @Override
    protected void initLogic() {
        registerApplicationLogin(MainInitLogic.class);
        registerApplicationLogin(ArticleInitLogic.class);
    }
}

4: 组件引入Library 冲突

通过gradlew   app:dependencies  查看依赖关系

具体解决冲突

api(rootProject.ext.dependencies["arouter-api"]){
    exclude group: 'com.android.support', module: 'support-v4'
}

5:组件间通信,继承ARouter

首先需要在Base module继承ARouter

compile引用arouter-api库, annotationProcesser是apt注解框架的声明

api(rootProject.ext.dependencies["arouter-api"]){
    exclude group: 'com.android.support', module: 'support-v4'
}
annotationProcessor rootProject.ext.dependencies["arouter-compiler"]

然后annotationProcessor 会使用javaCompileOptions这个配置来获取当前module的名字,在各个模块中的build.gradle的defaultConfig属性中加入:

javaCompileOptions {
    annotationProcessorOptions {
        arguments = [AROUTER_MODULE_NAME: project.getName()]
    }
}

每个模块的depencies属性需要ARouter apt的引用,不然无法在apt中生成索引文件,无法跳转成功

annotationProcessor rootProject.ext.dependencies["arouter-compiler"]

ARouter的初始化,在Application 中

if(AppCore.isDebugModel()){
    ARouter.openDebug();
    ARouter.openLog();
}
ARouter.init(AppCore.getApplication());

以Article 模块为例,ArticleActivity需要添加注解Route,path是跳转的路径

@Route(path = "/article/1")
public class ArticleActivity extends Activity implements ArticlesContract.IView 

使用ARouter跳转,build处填的是地址,withXXX处填的是参数key和value, navigation就是发射了路由的跳转。

ARouter.getInstance().build("/article/1")
        .withString("url","xxx")
        .navigation();

6:组件资源名冲突

在多moudule开发中,因为无法保证多个module中全部资源命名是不同的。假如出现相同情况,可能造成资源引用错误的问题。

解决办法有2种:

(1)在一开始命名的时候,不同模块间的资源命名都不一样,这是代码编写规范的约束

(2)使用Gradle的命名提示机制,使用resourcePrefix字段

android{
    resourcePrefix "组件名_"
}

7:build.gradle 和 gradle.properties 版本参数优化

config.gradle 统一配置版本信息

ext{
    android = [
            compileSdkVersion : 28,
            buildToolsVersion: "28.0.2",
            applicationId    : "com.xiongliang.component",
            minSdkVersion    : 16,
            targetSdkVersion : 27,
            versionCode      : 131,
            versionName      : "1.3.1",

            //是否开启日志输出
            MODE_LOGGER      : true,
            //是否开启测试环境
            MODE_DEBUG       : true,
            //是否打市场输出包(此标记=true,则上述自动为正式环境,关闭日志输出)
            MODE_MARKET      : false
    ]

    dependencies = [
            "okhttp"              : 'com.squareup.okhttp3:okhttp:3.8.1',
            "json"                : "com.alibaba:fastjson:1.2.54",
            "rxbus"               : "com.hwangjr.rxbus:rxbus:2.0.1",
            "butterknife"         : "com.jakewharton:butterknife:8.4.0",
            "butterknife-compiler": "com.jakewharton:butterknife-compiler:8.4.0",
            "smartrefresh"        : "com.scwang.smartrefresh:SmartRefreshLayout:1.1.0-alpha-20",
            "smartrefreshHeader"  : "com.scwang.smartrefresh:SmartRefreshHeader:1.1.0-alpha-20",
            "recycleview"         : "com.android.support:recyclerview-v7:28+",
            "glide"               : "com.github.bumptech.glide:glide:3.8.0",
            "arouter-api"         : "com.alibaba:arouter-api:1.4.0",
            "arouter-compiler"    : "com.alibaba:arouter-compiler:1.2.2"
    ]
}

gradle.properties 配置信息

# isModule 是集成开发模式和组件开发模式的开关,true 组件模式,false集成模式
isModule=false

参考:https://blog.csdn.net/guiying712/article/details/55213884

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值