编译时动态修改xml内容探索

背景:想在编译时按照配置文件修改xml中的特定字符串

android编译时,会在mergeResource任务中把三方依赖库、依赖module、自己的资源进行合并、汇总,最后保存到app/build/intermediates/res/merged/中,processResource的时候,从这个目录中拿数据,进行打包、链接等操作

AAPT时代

aapt时代,mergeResource之后,会在app/build/intermediates/res/merged/中暂存资源,xml文件也以xml的形式直接保存。只需要编写gradle插件,在mergeResource之后修改这些xml即可。processResource任务执行时,已经拿到的是修改后的xml

AAPT2时代

aapt2时代,mergeResource之后会在app/build/intermediates/res/merged/中暂存资源,但是这些资源也不再是普通的xml等文件,而是经过AAPT2编译后的二进制flat文件,这些文件修改起来没有xml那么简单。

开启了aapt2该怎么办

mergeResource负责把各个依赖的资源汇总出来,放到一起,processResource中会进行执行aapt2 link,所以只要在link之前,把app/build/intermediates/res/merged/中的flat修改/替换成我们要的文件即可

方案1

修改aapt2源码,让他在compile的时候做处理。(可行吗?类似atlas aapt)

方案2

解析flat二进制文件,然后重新写入(貌似是比较通用的方案)

方案3

debug了mergeResource源码发现mergeResource之后,会在app/build/intermediates/incremental/mergeReleaseResources/merger.xml生成一个文件,存放了资源情况,里面记录了所有资源的本地路径(在电脑中的)、所属包等情况。那么就可以解析这个文件,把资源copy一份,然后修改。最后把这些资源用aapt2进行一次主动编译,覆盖打包自动生成的那些flat文件即可。(看着可行,具体需要实践)

Debug Code

贴几个点,具体还是自己走一遍代码,才会有深刻的印象。

  • 给MergeResources的doFullTaskAction打一个断点,这里必会走
for (ResourceSet resourceSet : resourceSets) {
    resourceSet.loadFromFiles(getILogger());
    //里面把各个文件解析一下,比如items类的解析成item,创建成ResourceFile,layout类的不解析。最后要checkItems检测是否重复
    merger.addDataSet(resourceSet);
}
  • ResourceSet中读取每一个xml文件createResourceFile,创建成ResourceFile
    根据type来,列入values.xml这种文件需要解析成item进行合并。xxx.layout这种不用解析
    ResourceSet中processNewResourceFile应该会把每个item添加到mItems中
for (String dataItemKey : dataItemKeys) {
    //遍历这些item
    //如果是style开头的需要merge
    //这里竟然用到了goto语句,牛逼。。。
    setLoop: for (int i = mDataSets.size() - 1 ; i >= 0 ; i--) {
            break setLoop;
    }
}
  • writeAdditionalData方法会把所有的资源写在一起 ,跟标签是merge,包括item、style、layout、attr、图片。文件类型、来源等等。主要是item类型会罗列出来,文件类型如layout、图片等,形成file节点,存放在/rootProject/app/build/intermediates/incremental/mergeDebugResources/merger.xml
  • 以上,mergeResource就结束了

  • 断点过程中观察app/build/intermediates/res/merged/目录,发现走到doFullTaskAction的最后一行了,目录还是空的,但是放开之后,flat文件就生成了。直接追代码还不好追。
  • 在mergeResource的doFullTaskAction方法中断点观察路径,发现destinationDir就是merged目录,那想办法看这个目录在哪用了
  • MergedResourceWriter#mRootFolder就是那个目录,Writer中搜rootFolder,发现构造了一个CompileResourceRequest。
  • mResourceCompiler.submitCompile(request);构造好之后,还进行了submit。
  • 给这里打断点,跑程序,发现确实这里for循环了所有的资源,说明这是编译的入口。
  • 直接点源码进去WorkerExecutorResourceCompilationService,发现添加到requests集合中了,一看就是一个生产者消费者模式。
  • WorkerExecutorResourceCompilationService有一个成员变量workerExecutor,顾名思义,执行者
  • 点进去,果然有submit方法,可能他的实现,用了futures,执行编译任务。那具体的实现在哪呢
  • 看WorkerExecutorResourceCompilationService的注释Resource compilation service built on top of a Aapt2Daemon and Gradle Worker Executors.
  • 搜Aapt2Daemon,是一个守护进程,看方法就知道,编译操作都在这里完成。
  • 之后的源码都没法直接点,as上scroll from source,滚到这个文件处,发现aapt2编译相关源码都在这个包,那就好找了。
  • 最后附上一张图,编译就是执行这个命令


    image.png

以上用了将近半天的时间,收获不小,也了解了一些编译细节。debug源码还是很重要,相对读源码来说,要简单多了,要经常实践。如有错误,欢迎指正。

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

推荐阅读更多精彩内容