我在前一篇文章有写关于权限删除和收口的文章,使用的是 hook 打包流程的方案,后来有朋友告知我有一种写法是 tools:node="remove" ,这样可以直接删除三方 SDK 里的权限,讲实话我也是被他说之后才知道有这么一个写法。比如三方 SDK 里有使用 INTERNET 权限,我想移除它,那只需要在自己的 AndroidManifest.xml 里这么写即可:
那么来研究一波是这样是如何实现的。
上篇文章也说了,APK 里的 AndroidManifest.xml 其实是被引入的各个 AndroidManifest.xml merge 出来的,具体实现代码可以看 com.android.build.gradle.tasks.MergeManifests 。
下面直接分析下关于 tools:node="remove" 怎么玩的,先看下调用链:
MergeManifests#doFullTaskAction()
🔽
AndroidBuilder#mergeManifestsForApplication()
🔽
ManifestMerger2#merge()
🔽
ManifestMerger2#processOptionalFeatures()
调用链到这个位置就可以开始分析下源码:
当我们使用了 tools:node="remove" 后将会走进上图的 if 里,然后在 ToolsInstructionsCleaner#cleanToolsReferences() 里执行具体操作,还是以 INTERNET 权限为例:
上图 namedNodeMap 内 nodes 会有两个元素,分别是 android:name="android.permission.INTERNET" 和 tools:node="remove",接着遍历 nodes。
SdkConstants.TOOLS_URI 是 http://schemas.android.com/tools,tools:node="remove" 因此走进 if ,它的 localName 和 nodeValue 分别满足 node 和 remove 条件,于是执行 element.getParentNode().removeChild(element); 删除权限。
tools:node 还有些别的值可以使用,有空可以玩玩。