Android彻底组件化—代码和资源隔离

得到Android组件化方案已经开源,参见Android组件化方案开源。方案的解读文章是一个小的系列,这是系列的第三篇文章:
1、Android彻底组件化方案实践
2、Android彻底组件化demo发布
3、Android彻底组件化-代码和资源隔离
4、Android彻底组件化—UI跳转升级改造
5、Android彻底组件化—如何使用Arouter

最近Google正式推出AS3.0版本,同时gradle插件也升级为3.0.0,目前各大开源库都在做gradle3.0.0的兼容,我也把得到开源的组件化方案JIMU进行了升级,结论是:JIMU在gradle3.0上是没有兼容问题的,可以直接使用。关于如何迁移到gradle3.0.0,请参见官方迁移指南

虽然没有兼容问题,但在升级的过程中也收获了意外之喜,那就是发现gradle3.0.0对代码隔离的支持越来越好。为什么对“代码隔离”这么关注呢?大家可以回顾前两篇文章Android彻底组件化方案实践Android彻底组件化demo发布,在这两篇文章中提到的JIMU组件化方案,被我冠以“彻底”二字,虽然有些说大话,但主要是为了强调JIMU与之前其他组件化方案的不同之处就在于,JIMU实现了组件之间的绝对隔离,不同组件之间在代码开发阶段是完全不可见的,是一种彻底解耦的思想。为了实现这种隔离,我人为在编译和运行期做了一次判断和区分,既在编译期间(开发期间)组件之间没有任何依赖关系,但在打包和运行时,再偷偷添加依赖。具体可以参见前两篇文章和github源码

不得不说,当时这种实现是迫不得已,我本来想直接使用gradle提供的功能来做这种隔离,其实gradle也的确提供一个类似的功能,那就是apk依赖语法,其作用就是保证依赖库只在运行期间对外可见,但在编译期间是不可见的。按说这已经满足我的要求了,但是遇到了一个坑:在gradle2.+版本,apk依赖只能是jar,不能是aar,但是我们的组件因为含有各种资源,输出产物就是aar!所以最终选择了放弃apk这种语法。

而在最新的gradle3.0.0上,apk被替换为runtimeOnly语法,其作用还是一样的,但是我发现runtimeOnly可以添加aar依赖!这的确让我很兴奋,这不就是我梦寐以求的功能吗?有了这个尚方宝剑,组件化的方案就可以做的更薄了啊。于是我对在得到app上进行了实验,结论是:runtimeOnly的确可以解决一些问题,但是还不够。下面我从代码隔离、资源隔离和调试切换(单独和集成)三个方便仔细阐述,也顺便再讲一下JIMU所能实现的功能。

一、代码隔离

在讲代码隔离之前,先大致看一下gradle3.0.0对添加依赖的语法变化。

首先compile被废弃了,而是分成了两个:implementation和api,其中api与之前的compile功能基本一致,不再赘述;implementation就比较高级了,其作用就是,使用implementation添加的依赖不会再编译期间被其他组件引用到,但在运行期间是完全可见的。这也是一种代码隔离。举个例子,

组件A依赖lib1,既A implementation lib1
组件B依赖组件A,既B api A

在gradle3.0.0之前,B是完全可以引用到lib1里面的类的,但是现在B在编译期间就做不到了,只能在运行期可以。这种思想有点类似于“下属的下属不是你的下属”的思想。但是这种隔离在组件之间是不起作用的,在上面的例子中A的所有类对B还是完全可见的,也就是没有做任何隔离的。不过implementation的确是一种有效减少编译时间的方式,还是上面的例子,lib1发生了变化,现在只需要编译A就可以了,而在之前B有可能也使用到了lib1,所以需要同时编译B和A。按照官方建议,大部分情况下都应该使用implementation来进行添加依赖。

此外还有两种变化,原来的apk语法被runtimeOnly取代,provided被compileOnly取代,其作用还是没变。上文也讲了,runtimeOnly有个极大的改动就是可以支持aar了,但是compileOnly还是只能支持jar!

先做一个小结,目前gradle3.0.0的四种语法的功能和代码隔离效果见下图:

四种语法的功能和代码隔离效果

从上图可以看出,在代码隔离效果上,runtimeOnly的效果是最好的!但是就可以直接使用了吗,答案是否定的

二、资源隔离

在前面的文章中,一直在强调代码隔离,其实组件之间的完全隔离还有一层就是资源隔离,否则还是容易造成组件之间的耦合。这个在文章的“单独调试”章节中提到了一句,就是每个组件都需要指定一个资源前缀resourcePrefix,以避免集成后资源名冲突的问题。也就是说,一个彻底的组件化不仅要做到代码不能直接引用,资源也是不能引用的!

但是runtimeOnly目前还做到资源隔离,我在JIMU的开源库上做了试验,app通过runtimeOnly引用sharecomponent组件,虽然sharecomponent的代码是不可见了,但是资源还是可以被app直接使用的并能成功运行。

从这一点上看,直接替换成runtimeOnly是不行的,为了达到这种效果,目前还是需要像JIMU一样,人为的加一层控制,所以从组件化方案的角度上看并没有变的更薄,不过幸好JIMU已经很简单了,有一定的gradle基础的人可以比较容易的理解。

三、调试切换

除了上面说的资源隔离导致不能直接用runtimeOnly之外,还有一个使用上的问题需要解决,这也是JIMU中compbuild插件提供的一个功能:自动切换单独调试和集成调试。在单独调试时,组件是一个application工程,其输出产物是apk文件,而在集成调试时,被依赖的组件是一个library工程,其输出产物是aar文件。对于runtimeOnly来说,对aar和jar是支持的,但是不能支持apk,所以如果想在单独调试和集成调试之间切换的话,需要人工修改runalone配置并修改build.gradle配置文件,然后还需要sync之后才能生效,这种修改是相当繁琐的。

在JIMU中,这个问题的解决是通过“智能”识别当前要调试的组件来解决的,对于要调试的组件将其设置为application工程,而将其依赖的其他组件默默修改为library工程,这种修改是即时生效的,对开发者是完全透明的。开发者直接点击AS的run功能区就可以随意的调试任意组件。AS的run功能区的图如下:


随意的调试切换

四、总结

综上所述,我们对JIMU和gradle3.0.0做几点总结:
(1)升级到gradle3.0.0之后,可以继续使用JIMU,不需要专门做兼容
(2)gradle3.0.0提供了implementation和runtimeOnly两种语法,它们都能实现一定程度的代码隔离效果,建议大家在今后优先使用
(3)implementation和runtimeOnly目前在资源隔离和调试切换上还不能满足组件化的要求,所以还是需要使用JIMU提供的完全隔离和随意切换功能。

在JIMU的源码中我增加了gradle3.0.0分支,依赖语法做了相应的替换源码地址:DDComponent

JIMU的讨论群,群号693097923,欢迎大家加入:


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

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,566评论 25 707
  • 得到Android组件化方案已经开源,参见Android组件化方案开源。方案的解读文章是一个小的系列,这是系列的第...
    格竹子阅读 84,054评论 196 405
  • 什么是组件化?组件化开发就是将一个app分成多个模块,每个模块都是一个组件(Module),开发的过程中我们可以让...
    码农一颗颗阅读 4,773评论 2 16
  • 3月,有何不同? 本来想着明天写总结,做复盘,做月计划的,突然想到今晚没有什么想写的话题,便把3月总结拿来凑凑数。...
    柚子粒阅读 192评论 0 0
  • 读猫叔逝去的味道,有感而发 还依稀记得第一次看到不语老师的微博,组织一次猫说共读,毫不犹豫的就报名参加了,最近太浮...
    liny52阅读 233评论 0 0