新出炉:解决 Android Manifest Merge 冲突的小插件 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
2bab
V2EX    Android

新出炉:解决 Android Manifest Merge 冲突的小插件

  •  1
     
  •   2bab 2017-05-23 20:28:15 +08:00 14076 次点击
    这是一个创建于 3140 天前的主题,其中的信息可能已经有所发展或是发生改变。

    原文地址

    Seal-Github

    最近做些 SDK 升级时,有些包引入后会有诸如此类的报错:

    AndroidManifest.xml:22:9-40 Error: Attribute application@theme value=(@style/AppTheme) from AndroidManifest.xml:22:9-40 is also present at [some:libraries:version] AndroidManifest.xml:9:18-62 value=(@style/AnotherTheme). Suggestion: add 'tools:replace="android:theme"' to <application> element at AndroidManifest.xml:18:5-65:19 to override.

    这是一个很常见的错误了,照着提示做 replace 就 OK 了。但是当我加上 replace 的代码后,发现依旧报错:

    Multiple entries with same key: @android:theme=REPLACE and android:theme=REPLACE.

    百思不得其解,查看了一下依赖库的 AndroidManifest.xml 源码,发现它也设置了tools:replace="android:theme",而 Manifest Merger 把这个视为冲突抛了出来。

    思考

    如果只是跟着 官方的 Manifest Merge,这个问题恐怕无解。StackOverflow 上也有人问过这个问题,但是没有更多的解法回复。

    为什么依赖库会想不开去设置 replace 属性呢?很大的一个可能是:他也碰到了他的依赖库和他的 Manifest 有冲突的情况。那么我们能做什么?我们始终还是想要把他的某些属性给替换掉的( theme/allowBackup/...),不管他是出于什么样的目的,都不能阻止我想打出包的心!

    解法

    通过简单的观察和源码查看,我们发现 merge 是发生在 process${variant}Manifest 这个 Task。那么就得想办法在执行这个任务之前 Precheck 一下所有依赖的 AndroidManifest.xml

    Seal - A gradle plugin to do precheck of Android Manifest.

    我写了一个简易的插件来做这件事,目前支持两个功能:

    1. 删除 Application 节点的某些属性,如 debuggablethemeallowBackup
    2. 删除 Application 节点中 tools:replace 属性的某些值,如 android:iconandroid:themeandroid:allowBackup

    这个插件不仅能解决上述提到的问题,还能顺带修复诸如下面这种 Warning:

    Warning: AndroidManifest.xml already defines debuggable (in http://schemas.android.com/apk/res/android); using existing value in manifest.

    而我们所需要做的,仅仅是指定我们不需要 libraries 的那些属性:

    def projectRoot = project.getRootProject().rootDir.absolutePath // 依赖库的 Manifest 文件搜索路径 // 1. Gradle plugin 2.3.0 或者更高版本,会默认开启 build-cache 功能,Release 版本的库会解压到这里 // 2. 但是我们同样需要对 SNAPSHOT 的库做预检查,所以还需要加入 exploded-aar 的目录 // 3. 有更多自定义的目录或者 module,请自行添加 def manifestPath = [ // for AAR of Release // see note below projectRoot + '/build-cache', // for AAR of SNAPSHOT projectRoot + '/app/build/intermediates/exploded-aar' ] def removeAttrs = [ 'android:debuggable' ] def replaceValues = [ 'android:allowBackup' ] seal { enabled = true manifests = manifestPath appAttrs { enabled = true attrsShouldRemove = removeAttrs } appReplaceValues { enabled = true valuesShouldRemove = replaceValues } } 

    需要注意的是,如果开启了 build-cache, Seal 建议你把 build-cache 的文件夹放在工程目录内(就是上面配置里的 build-cache 位置)。

    //gradle.properties android.buildCacheDir=./build-cache ... 

    更多信息,请参考 Github 仓库内的说明,欢迎大家提 PR 和 ISSUE。

    2 条回复    2017-07-23 16:14:22 +08:00
    lastmayday
        1
    lastmayday  
       2017-05-23 23:45:14 +08:00
    超棒 der!
    veightz
        2
    veightz  
       2017-07-23 16:14:22 +08:00
    好棒棒~
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2531 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 23ms UTC 15:18 PVG 23:18 LAX 07:18 JFK 10:18
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86