Android模块化开发探索
来源:互联网 发布:淘宝搜索权重模型 编辑:程序博客网 时间:2024/06/06 17:23
随着业务的不断发展壮大,移动端所承担的功能也越来越重,特别是代码几易其主之后开始变得杂乱无章,牵一发而动全局的事情时常发生。为了应对团队壮大之后的开发模式,我们必须要对业务进行隔离,同时沉淀出通用组件,完善移动开发的基础设施。
一、痛点
模块化以前,我们主要面临以下几个痛点:
- 业务边界不清晰
- 通用代码与业务代码耦合
- 代码重复、资源重复
- 代码散乱、常亮漫天飞
- 代码臃肿 等
其中业务边界不清晰是最大的痛点,最直接的表现就是处处有雷,经常会引入新的 Bug,而且很多 Bug 往往不能从根本上解决,代码维护成本居高不下。
二、重构原则
模块化并不能一蹴而就,我们在重构的同时也在做新需求,每次看到那一坨旧代码心中就会有无数只”草泥马”奔腾而过,干脆重写的无奈之情难以抑制,结果在红牛的日夜陪伴下写出来的新代码虽然看上去“漂亮”,但是实际上问题更多,得不偿失。总结了重构的三项基本原则:
1、渐进式重构
如果一段代码已经比较稳定,可以从中抽取一部分功能重写,不要一上来就全部推翻重写,可以慢慢淘汰掉老代码。
2、理清业务再动手
App 作为业务链的末端,由于角色所限,开发人员对业务的理解比后端要浅,所谓欲速则不达,重构不能急,理清楚业务逻辑之后再动手。(可以找熟悉业务的同学聊一下 — PD、后端、测试)
3、Android、IOS互相参考
业务代码总是惊人的相似,两端互相参考的过程中,不但可以 Review 代码,还能加深对业务的理解,可谓一举两得。
实践证明,如果人手紧张,项目早期可以只让一端的开发人员跟需求,另一端直接“翻译代码”,甚至一个人写两端代码。
三、模块化过程
所谓模块化,是一个分而治之的过程,首先进行垂直拆分,过程中必然会催生出业务共享的 Common 模块,而 Common 又可以继续水平拆分,逐渐变薄,直到 Common 消失。
刚开始模块划分可以简单点:
1、抽取Common
Common 层服务于所有的上层业务,是通用层,不允许引用业务层代码。
- 首先把 Common 层用到的 Business 层代码下放到各个业务
- 然后把多个 Business 之间共用的代码提取到 Common 层
- 资源文件的处理方式与代码一致
但抽取Common不是终点,随着代码结构逐渐变得清晰,在业务隔离的同时,不断丰富 Common 模块,然后在某个节点将其再拆分成一个一个独立模块。
2、业务隔离
业务模块之间不能互相依赖,只能单向依赖 common。
业务之间存在两种耦合关系:
- 页面耦合
- 功能耦合
要做到彻底隔离就必须解决这两种耦合关系:
- 页面解耦 - 跳转协议
- 功能解耦 - 模块间 RPC
2.1 跳转协议
页面解耦可以借鉴 Web 的设计原理,给业务模块中对外的页面定义一个 URI,然后页面之间通过 URI 跳转。
举个栗子,A、B 两个页面分属于不同的业务模块,在页面未解耦之前,A 如果要跳转到 B,必须要依赖 B 的模块,那么跳转代码会写成如下形式:
Intent intent = new Intent(getContext(), BbbActivity.class);intent.putParcelable(BbbActivity.EXTRA_MESSAGE, message);startActivity(intent);
如果 A、B 之间还需要传递数据,就要共享常量、Model,耦合继续加重。
如果我们为 B 页面定义一个 URI - wsc://home/bbb,然后把共享的 messageModel 拍平序列化成 Json 串,那么 A 只需要拼装一个符合 B 页面 scheme 的跳转协议就可以了。
wsc://home/bbb?message={ “name”:”John”, “age”:31, “city”:”New York” }
URL Router 有很多种实现方式,网上资料也是多如牛毛,这里只提供一种思路。
<activity android:name=".ui.BbbActivity"<intent-filter> <category android:name="android.intent.category.DEFAULT" /> <action android:name="android.intent.action.VIEW" /> <data android:host="bbb" android:path="/home" android:scheme="wsc" /></intent-filter></activity>
final Uri uri = new Uri.Builder().authority("wsc").path("home/bbb").appendQueryParameter("message", new Gson().toJson(messageModel)).build();final Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(uri);startActivity(intent);
2.2RPC
Android 通过 interface 提供服务,即回调或监听器模式或观察者模式。它的优势在于可以只在业务提供方的 module 中定义interface,解耦更彻底。
2.3 主项目Module
但我们一般会在各业务模块Module之上,再创建主项目的Module,它依赖于各模块Module,通过它来实现各模块间的交互和页面跳转。
四、代码管理
如果被隔离的业务模块仍然在一个 Project 中,就无法从“物理”上彻底隔绝代码间的相互引用,我们需要从工程上保证业务之间互相独立。
每一个 subProject 可以独立发版,然后通过坐标依赖组装成 App。
五、另外
实现模块化开发,有两种思路:组件化开发和插件化开发:
以上我们介绍到的就是组件化开发,将各功能模块分离成相互独立的组件,最后由主module来集成调度;
插件化开发一般适用于不是必选功能,而是使用时下载插件的功能,例如:皮肤包、银联插件化开发等。
扫描二维码,加入我们,获取更多资讯!
- Android模块化开发探索
- Android 模块化探索与实践
- android studio模块化开发
- Android模块化开发
- Android开发资源模块化
- Android 模块化开发
- Android组件化、模块化开发
- Android组件化模块化开发
- Android开发艺术探索
- Android 项目模块化开发,提高开发效率。
- android 插件化 模块化开发(apkplug)
- android 插件化 模块化开发(apkplug)
- Android应用开发的插件化 模块化
- Android插件化,热修复,模块化开发
- Android 开发:由模块化到组件化
- Android--开发:由模块化到组件化
- Android模块化开发--路由ARouter日常使用
- 模块化开发
- jsp网上商城jsp课程设计
- 浅谈PSR规范与PHP框架中类的自动加载原理
- 用模态的方式打开自定义JDialog,并获取返回值
- 微信JSAPI支付开发说明和注意事项
- JavaScript基础之层级选择器
- Android模块化开发探索
- 强化学习之Policy Gradient
- 1. linux C -- 进程锁
- SDWebImage的使用
- System 命名空间
- dubbo 后台管理dubbo-admin
- 反射_程序集_额外补充2(将"123"转"壹贰叁"的stringbuilder打包成程序集类库的方法)
- MetricsSystemImpl.register
- 提高代码质量-工具篇