Android组件化开发思想与实践

作者:popular_linda
链接:https://juejin.im/post/5eb019b8e51d45338806f2c0
 
什么是组件项目按功能拆分成功若干个组件 , 每个组件负责相应的功能 , 如login、pay、live 。组件化与模块化类似 , 但不同的是模块化是以业务为导向 , 组件化是以功能为导向 。组件化的颗粒度更细 , 一个模块里可能包含多个组件 。实际开发中一般是模块化与组件化相结合的方式 。
 
为什么要组件(1)提高复用性避免重复造轮子 , 不同的项目可以共用同一组件 , 提高开发效率 , 降低维护成本 。
(2)项目按功能拆分成组件 , 组件之间做到低耦合、高内聚 , 有利于代码维护 , 某个组件需要改动 , 不会影响到其他组件 。
组件化方案
组件化是一种思想 , 团队在使用组件化的过程中不必拘泥于形式 , 可以根据自己负责的项目大小和业务需求的需要制定合适的方案 , 如下图就是一种组件化结构设计 。

Android组件化开发思想与实践

文章插图
  • 宿主App
    在组件化中 , app可以认为是一个入口 , 一个宿主空壳 , 负责生成app和加载初始化操作 。
  • 业务层
    每个模块代表了一个业务 , 模块之间相互隔离解耦 , 方便维护和复用 。
  • 公共层
    既然是base , 顾名思义 , 这里面包含了公共的类库 。如Basexxx、Arouter、ButterKnife、工具类等
  • 基础层
    提供基础服务功能 , 如图片加载、网络、数据库、视频播放、直播等 。
注:以上结构只是示例 , 其中层级的划分和层级命名并不是定性的 , 只为更好的理解组件化 。
组件化面临的五问题
 
一 , 跳转和路由Activity跳转分为显示和隐示:
//显示跳转Intent intent = new Intent(cotext,LoginActivity.class);startActvity(intent) //隐示跳转Intent intent = new Intent;intent.setClassName("app包名" , "activity路径");intent.setComponent(new Component(new Component("app报名" , "activity路径")));startActivity(intent); 1、显示跳转 , 直接依赖 , 不符合组件化解耦隔离的要求 。
2、对于隐示跳转 , 如果移除B的话 , 那么在A进行跳转时就会出现异常崩溃 , 我们通过下面的方式来进行安全处理
//隐示跳转Intent intent = new Intent;intent.setClassName("app包名" , "activity路径");intent.setComponent(new Component(new Component("app报名" , "activity路径")));if (intent.resolveActivity(getPackageManager) != ) { startActivity(intent);}startActivity(intent);原生推荐使用隐示跳转 , 不过在组件化项目中 , 为了更优雅的实现组件间的页面跳转可以结合路由神器ARouter , ARouter类似中转站通过索引的方式无需依赖 , 达到了组件间解耦的目的 。
Aouter使用方式如下:
1、因为ARouter是所有模块层组件都会用到所以我们可以在Base中引入
api 'com.alibaba:arouter-api:1.5.0'annotationProcessor 'com.alibaba:arouter-compiler:1.2.2'2、在每个子module里添加
Android { defaultConfig { ... JAVACompileOptions { annotationProcessorOptions { arguments = [AROUTER_MODULE_NAME: project.getName()] } } }}【Android组件化开发思想与实践】annotationProcessor会通过javaCompileOptions这个配置来获取当前module的名字 。
3、在Appliction里对ARouter进行初始化 , 因为ARouter是所有的模块层组件都会用到 , 所以它的初始化放在BaseAppliction中完成 。
public class BaseApplication extends Application { @Override public void onCreate { super.onCreate; initRouter(this); } public void initRouter(Application application) { if (BuildConfig.DEBUG) { // 这两行必须写在init之前 , 否则这些配置在init过程中将无效 ARouter.openLog; //打印日志


推荐阅读