前言
强烈推荐先阅读这篇文章 Android 组件化最佳实践
本文是阅读实践后的思考总结,更倾向实践步骤。
组件化开发架构
组件化开发大体就是这样的架构,最关键的是base
和 base_custom
组件内容的区别化。
这里涉及两个概念 模块化 和 组件化,这两个本质上是一样的,都是为了降低代码耦合性,区别就在于内容,组件化都是单一功能的集合,模块化就是独立业务线的集合,其实我们都可以称之为组件化。
组件化开发步骤
第一步:创建组件
File——>New——>New Moudle——>Phone & Tablet Moudle
创建后是一个工程,类似app,会默认创建好相关资源文件。「业务模块首选」
File——>New——>New Moudle——>Android Library
创建后是一个moudle「组件首选」
第二步:编码
编码过程中需要注意的就是 资源和代码的聚合,还是遵循 自己的事情自己做 的原则,降低耦合性。
-
资源
-
图片资源
drawable
,需要用到的放在自己目录下,类似共用的返回键这种,放在基础组件中; -
颜色值
color
,不要共用,没多少,写在自己组件中; -
尺寸
dp
,这个基本没啥变化,可以放到基础组件中; -
样式 style,涉及到Activity主题的,这个可以在基础组件中定义,组件中继承,这样既保证了整个app风格,也可以特殊化。
-
为了保证 组件内资源 的 充分隔离,我们可以 规范命名,以模块化命名,这样的外部调用时,不容易出错。
例如 登录模块
ic_login_phone
login_phone_hint_text
...严格一点,可以在
build.gradle
文件中配置 命名前缀,这样编码时 不按照这种格式,就会飘红。只针对xml文件,图片还需自己规范命名。android { resourcePrefix "login_" // 其他配置 ... }
-
-
代码
- 共用的基类,工具类等放在基础组件中
- 为了防止外部直接引用 组件内的类,可以在集成到工程中时 采用
runtimeOnly
dependencies { ... runtimeOnly project(':moudle_shop') }
第三步:调试配置
代码写好后,需要 单独调试 或 集成到app中调试,那就需要配置两种模式。
- 创建
gradle.properties
文件,定义属性用来区分两种模式
//例如 false表示集成调试,true表示单独调试
isSingleRun = false
-
在
build.gradle
文件中配置- 配置工程类型
if (isSingleRun.toBoolean()) { //单独调试 应该是工程类型 apply plugin: 'com.android.application' } else { //集成调试 则作为library集成到app中 apply plugin: 'com.android.library' } android{ ... } ...
- 配置
applicationId
android{ defaultConfig { //单独测试 需要配置applicationId if (isSingleRun.toBoolean()) { applicationId "com.xx.moudle_xx" } } }
- 配置
AndroidManifest.xml
单独测试是需要一个启动页入口的,所以清单文件也需要配置
android{ sourceSets { main { if (isSingleRun.toBoolean()) { //单独测试 新建一个文件夹manifest,存放清单文件,设置启动页入口 manifest.srcFile 'src/main/manifest/AndroidManifest.xml' } else { manifest.srcFile 'src/main/AndroidManifest.xml' } } } }
- 配置
Applcation
每个组件,都会有需要初始化的东西,共用的(比如:网络框架,图片框架)可以在基础组件中初始化,那么一些自己模块需要初始化的东西,该怎么做?因为集成测试不会初始化 组件的
Application
。这里我们可以在基础组件中定义
BaseApp
4. 组件 Application 的动态配置 -
至此,调试配置完成,配置的目的就是为了方便 组件 独立开发时测试 以及 集成到app时测试。将
gradle.properties
文件中的isSingleRun
属性设置为true
,测试一下配置是否成功。
第四步:调试测试
-
将
isSingleRun
设置为true
,就可以 单独调试 了,像 app 工程那样。 -
将
isSingleRun
设置为false
,然后集成到app
中就可以 集成测试 了。集成测试这里有个问题,如何跳转到组件中的 Activity呢?需要用到 Alibaba 开源的 ARouter
推荐阅读 Android 组件化最佳实践 中的 四、组件间界面跳转。
ARouter配置步骤:
base组件中配置
build.gradle
android { defaultConfig { ... javaCompileOptions { annotationProcessorOptions { arguments = [ moduleName : project.getName() ] } } } } dependencies { api 'com.alibaba:arouter-api:1.3.1' // arouter-compiler 的注解依赖需要所有使用 ARouter 的 module 都添加依赖 annotationProcessor 'com.alibaba:arouter-compiler:1.1.4' }
组件中配置
android { defaultConfig { ... javaCompileOptions { annotationProcessorOptions { arguments = [ moduleName : project.getName() ] } } } } dependencies { ... annotationProcessor 'com.alibaba:arouter-compiler:1.1.4' }
在app主程序
Application
中初始化//这断必须写,否则不生效,本以为我不需要打印日志,没写这段,结果花费好长时间找bug if (BuildConfig.DEBUG) { // 这两行必须写在init之前,否则这些配置在init过程中将无效 ARouter.openLog(); // 打印日志 ARouter.openDebug(); // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险) } ARouter.init(this);
组件中被启动Activity 配置 path,path 必须是 ”/“ 开头,最少两级
@Route(path = "/test/test") public class TestActivity extends BaseActivity {}
主程序启动 组件中 Activity
ARouter.getInstance().build("/test/test").navigation();
-
至此,单独调试 和 简单的集成调试 完结,接下来更多的就是 集成调试情况下,如何保证组件在高度聚合的情况下互通有无。
组件间数据传递
整体思路就是在基础组件中定义接口,组件间通过接口传递数据,完全解耦。