Android模块化实践

前言

  1. 什么是模块化
    项目由多个模块构成,模块间解耦、可重用,模块可通过aar依赖。每个模块都可以独立运行。
  2. 为什么要模块化
    当项目越来越复杂,体积也变得臃肿,为了降低复杂性和耦合度、提高模块重用性、单模块运行提高编译打包效率等等,模块化是很好的解决方案。

改造目标

  1. 项目拆分为多个子工程,大概有三类:基础组件、业务模块、聚合业务模块的app模块.结构图如下:


    perfect.png

    其中app模块是application工程,其他模块都是library工程,library工程可以打成aar上传maven,使用maven依赖。

  2. 业务模块之间通过路由、ioc服务实现通信,减少相互依赖,降低耦合性。
  3. 业务模块可以独立运行,开发期间只需运行自己的模块,减少编译打包时间。

遇到的问题

  1. 拆分不彻底或重复资源
    我加入项目的时候,很多业务模块已经从app模块拆分出来,但主要是代码移动,其对应的so,资源文件,manifest声明却在app模块或base模块,而且app启动时的各个组件初始化也分布在很多地方。在尝试独立运行业务模块时常常会出现缺少组件或找不到类编译时或运行时报错。另外,由于子工程是由原单一工程拆分而出的,有些资源文件或类产生了重复,增大了apk体积。

  2. 模块间依赖关系复杂
    上面的架构图是理想状况,但实际项目大概是这样的:


    real.png

    可以看到,很多业务模块依赖别的业务模块,而且依赖层级很深。这样就违背了模块化改造的初衷,耦合性并没有降低多少,各个业务模块也不能独立开发,修改代码牵一发而动全身。而且由于编译时要处理各个模块的依赖关系导致编译时间的大幅提高。

  3. 底层模块耦合业务
    由于一些历史原因,base模块下的几个模块中有业务相关代码,可能经常需要修改。这就导致了其不能打成aar放在maven上,只能以源码形式进行依赖。

  4. base模块膨胀
    各个业务模块之间往往需要通信,而且也会有很多共同依赖的资源文件。所以不能避免的需要将一些bean类和资源文件放置在base模块中。长此以往,base模块会变得越来越大。

解决方案

  1. 模块拆分
    我觉得可以遵守以下几点原则:
  2. 要把每个模块看成独立的app:每个模块的所有资源(.java、resources、manifest声明、lib库、so文件)都必须拆分到自己的模块.可以通过能否独立运行来校验是否有遗漏.
  3. 最小作用域:对于java类和资源文件,尽量做到最小作用域,能放到上层业务模块内就不要放到下层公共依赖工程中.
  4. 命名规范:资源文件最好加上模块名prefix(可以在gradle文件中设置resourcePrefix来警告不符规范的资源),另外可以通过脚本来找重名文件,去除重复.
  5. 模块间通信
    要解决模块间的依赖,最重要的就是模块间通信,通过模块通信方式来减少直接依赖,我们项目现在主要采用了以下的通信方法:
  6. activity路由
    关于这个网上已经有了很多文章,我们项目的实现方法也类似.通过一段字符串(如/modulea/DemoActivity)来标志某个activity,然后通过路由框架来获取activity的class,实现跳转.
  7. ioc服务
    除了activity跳转肯定还有大量其他需求,我们项目使用了ioc服务来完成.(此服务与android原生service概念类似,但并非android原生的service).简单的说就是在下层公共模块中定义一个功能接口(或抽象类)serviceA,然后在上层模块moduleA中创建了serviceA的实现serviceAImpl,上层模块moduleB(不依赖模块moduleA)通过ioc框架获取serviceA后就可得到真正的实现类.
    每个模块都可以把自己需要被其他模块调用到的功能以服务的方式提供出来,而其他模块只要有功能接口就可以使用服务.
    这个ioc框架的实现原理也比较简单,就是通过注解标注出功能接口实现类,然后利用注解处理器在编译时生成记录接口与实现对应关系的辅助类,在app启动时加载这些辅助类.这样ioc框架就能通过功能接口找到实现类了.和阿里的arouter类似
  8. 基础组件业务无关
    从后期优化、维护方便等角度来说,网络、图片加载、持久化等基础组件都应该是业务无关的。所以对于这些组件中耦合业务的情况应该尽早重构修改。最好是将这些基础组件独立仓库,独立版本号,通过maven依赖来使用。如第一张图所示,可以在上层业务模块与基础组件中间的base模块中引入基础组件,并进行一些业务相关的配置。
  9. 合理划分模块
    对于base模块膨胀的问题,其实关键还在于业务模块间划分不明确,导致很多view、业务组件需要重用。模块间通信只能解决一部分问题,最主要的还是要明确模块间要有明确的边界、合理划分模块,尽量让每个模块间独立起来,减少通信需求。

本文只是我们项目和我的一些想法、做法,有什么意见还望大家指正。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容