android组件化开发和总结

为什么会需要组件化

随着项目的发展,业务逻辑越来越复杂,代码量越来越多,会带来:

  • 各种业务模块耦合在一起,不利于维护,不利于新入职成员的阅读
  • 改动一个小功能,就要重新编译整个工程,编译时间较长
  • 代码量越来越大,不利于对代码的拆分
  • 对于测试,新功能无法单独测试
    这样就需要使用组件化和插件化

什么是组件化

组件化:模块组件和通用组件,可分为业务组件和UI组件等等,比如下拉刷新可作为通用ui组件,供多个项目调用,登录模块或者网络模块,可作为通用业务组件存在,供多个项目使用。
在项目开发中,讲项目拆分为不同的组件,开发阶段组件可单独测试,通用组件可进行依赖服用,最后开发结束以后,将各个组件组合在一起,合并成真正的Apk
android组件化开发和总结_第1张图片
好处:

  • 业务组件可以并行开发
  • 每个组件根据程序员擅长的技术可以采取mvp,mvvm,mvc模式进行开发,不影响整个项目
  • 新入职成员,可单独熟悉一个模块,不需要熟悉整个项目,节约时间
  • 提高开发效率,开发人员只要维护自己单独的模块就可以了
  • 优秀的代码和重复的功能可以封装成通用模块,供其他项目使用
  • 测试可以单独测试模块
  • 可以有效避免某一功能出现问题,其他功能必须等待问题解决完成才能打包给测试的情况

什么是插件化

插件化:将一个APK划分为不同的"APK",比如常用的App换肤就是一个插件apk。将整个APK划分为主模块和附属模块,每一个模块都是一个apk,开发完成将主模块和附属模块进行打包
好处:

  • 对Apk模块进行模块解耦
  • 开发效率提升,并行开发
  • 动态升级
  • 按需要加载模块,节省内存

组件化和插件化总结

两者最终目的都是为了解耦模块,避免模块之间的依赖耦合,提升团队开发效率,都可以对单独的模块进行开发测试,组件化相对于插件化,开发相对简单,技术成本相对较低

组件化实现步骤

首先创建一个工程,名字叫ComponentApp
组件化和第三方SDK版本控制
组件化模块中含有多个组件和模块,可以将每个模块组件的build.gradle中的各种引用版本进行统一管理,统一配置以后,供其他模块使用
右击项目,创建一个file,命名为config.gradle,作用就是存储通用的引用的版本号,先看一下项目中的Build.gradle文件中的内容:
android组件化开发和总结_第2张图片
现在只有一个模块,如果有多个模块,如果一些引用的版本号进行改变,就需要对多个模块分别修改,首先是重复工作,还有就是容易遗漏,所以要将一些通用引用版本放在config.gradle中管理,现在将android和dependencies模块通用版本抽取到config.gradle中

ext{
    android=[
            compileSdkVersion:26,
            applicationId:"drag.mandala.com.componentapp",
            minSdkVersion:22,
            targetSdkVersion:26,
            versionCode:1,
            versionName:"1.0"
    ]

    dependencies=[
            supportV7:'com.android.support:appcompat-v7:26.1.0',
            constraintLayout:'com.android.support.constraint:constraint-layout:1.1.3'
    ]

}

然后在项目的build.gradle中写入apply from:"config.gradle"进行引用:

android组件化开发和总结_第3张图片
在模块的build.gradle中,引用config.gradle中定义的描述:
android组件化开发和总结_第4张图片
以后随着项目的扩大,会有更多的组件模块,这样每个模块的通用引用版本都可以抽取到config.gradle中,方便管理
动态切换application和lib模式
我们会将许多功能抽象出来,作为一个模块,这个模块,在单独开发的时候,作为application模式,可以单独运行,开发完成,转换成lib模式,作为主app的一部分,这个的关键,就是要动态的切换模式
先创建两个module,分别命名为modulea,modulebandroid组件化开发和总结_第5张图片
创建完以后的项目结构是:
android组件化开发和总结_第6张图片
主项目的settings.gradle
android组件化开发和总结_第7张图片
为了切换模式,需要在config.gradle中定义一个参数:isApplication=true
android组件化开发和总结_第8张图片
modulea和moduleb的build.gradle,和主app一样,根据config.gradle中的通用版本号进行配置,注意,作为lib是没有applicationId这个属性的,只有作为application才有,可以给modulea和moduleb分别取两个包名,作为切换为application的配置,根据apply plugin: 'com.android.application’和apply plugin: 'com.android.library’可以切换application和lib模式,这个modulea的具体配置是:
android组件化开发和总结_第9张图片
moduleb只要把包名改成自己的就行了,这样,修改config.build中的isApplication字段的true或false,然后再sync,就可以切换不同的模式了
lib和application模式中的AndroidManifest.xml合并
modulea中已经有一个AndroidManifest.xml,这个只是lib模式的配置,里边内容如下:
android组件化开发和总结_第10张图片
这个作为application模式的AndroidManifest.xml是不适用的,作为一个app,图标,启动页之类的是必须的,所以现在要在modulea的src/main文件夹下,建立两个文件夹,一个是debug,一个是release,分别新建两个AndroidManifest.xml,release文件夹下的AndroidManifest.xml,就是lib模式下的配置,debug文件夹下的,要作为application的配置,可以将主app中的AndroidManifest.xml拷贝下来,将所缺的资源文件也拷贝过来,新建一个默认的启动Activity,这里命名为LoginActivity,AndroidManifest.xml配置如下:




    
        
            
                

                
            
        
    


主结构如下:
android组件化开发和总结_第11张图片
还是根据isApplication字段来切换不同的AndroidManifest.xml,在build.gradle中的切换配置代码:

sourceSets {
        main {
            if (rootProject.ext.isApplication) {
                manifest.srcFile 'src/main/debug/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/release/AndroidManifest.xml'
                //移出debug下无用的资源
                java {
                    exclude 'debug/**'
                }
            }
        }
    }

android组件化开发和总结_第12张图片
这样,修改isApplication为true,就可以运行modulea,android组件化开发和总结_第13张图片
组件与主app的Application冲突与初始化
在moduleb中,按照以上步骤进行配置,创建一个Activity,名字为RegisterActivity,现在在modulea和moduleb中,分别新建一个debug包,创建一个Application,分别为LoginApplication和RegisterApplication,分别打印一些日志,在AndroidManifest.xml进行配置,
android组件化开发和总结_第14张图片
android组件化开发和总结_第15张图片
同样的,在主app中,创建一个MyApplication,在AndroidManifest.xml进行配置,打印一些日志,

public class MyApplication extends Application
{
    @Override
    public void onCreate()
    {
        super.onCreate();
        Log.e("MyApplication","MyApplication");
        //可以理解为第三方sdk的初始化
        Log.e("LoginApplication","LoginApplication");
        Log.e("RegisterApplication","RegisterApplication");
    }
}

这些日志可以理解为第三方sdk的初始化,就是LoginApplication和RegisterApplication作为application模式下的Application,会在里边进行一些第三方SDK的初始化,然后作为lib模式以后,要将这些初始化放到主app的Appliction。在主app的build.gradle中对modulea和moduleb进行引用
android组件化开发和总结_第16张图片
如果要这个sync成功,需要将isApplication设置为false,将modulea和moduleb作为lib模式
组件之间资源名的冲突
不同的组件,有可能会存在命名一样的资源名,这样在主app中组合的时候,会出现一些问题,最简单的解决方法就是保证命名的唯一性,这个可以在build.gradle中设置 resourcePrefix 属性,定义资源的前缀,这样就会规范命名
android组件化开发和总结_第17张图片
组件间的跳转通信
现在组件之间的跳转通信,一个是Intent跳转,一个是ActivityRouter
使用Intent跳转,需要在module中的release文件夹下的AndroidManifest.xml对需要跳转的Activity进行配置,设置一个重要的属性: android:exported=“true”
android组件化开发和总结_第18张图片
在主app中,通过Class.forName获取到需要跳转的Class,然后通过Intent进行跳转
android组件化开发和总结_第19张图片
可以在跳转到的Activity中接收传入的值
android组件化开发和总结_第20张图片
使用ActivityRouter进行跳转
ActivityRouter
在config.gradle中,对ActivityRouter的版本进行配置,

 activityrouter : 'com.github.mzule.activityrouter:activityrouter:1.2.2',
            activityrouterCompiler:'com.github.mzule.activityrouter:compiler:1.1.7'

在需要跳转的module和主app的build.gradle进行引用

 compile rootProject.ext.dependencies.activityrouter
    annotationProcessor rootProject.ext.dependencies.activityrouterCompiler

主app的AndroidManifest.xml配置RouterActivity


            
                
                
                
                
            
        

在需要跳转的module中的Activity进行配置
android组件化开发和总结_第21张图片
主app中进行跳转

  Routers.open(MainActivity.this,"modulea://LoginActivity?test=you+are+best");

还有一种跳转方法,是通过EventBus,这个可以作为一个选择

总结

组件化开发,将一些共同的库,比如网络库,下拉加载库之类的,封装成一个library,供其他module调用,将一些功能分成module,每个人开发的时候,module作为application进行开发,可以写一个入口Activity,比如入口Activity是MainActivity,用来启动这个module实际的功能,比如启动ActivityB,这个ActivityB就是该module的功能入口,开发完成以后,将module变成library,主app直接调用ActivityB

源码

组件化源码

你可能感兴趣的:(android开发技巧系列)