关于R8中keep规则与flattenpackagehierarchy、repackage功能交互行为的官方文档求证
关于R8中keep规则与flattenpackagehierarchy、repackage功能交互行为的官方文档求证
我完全懂你找官方文档的那种头疼——这种细节确实容易在官方文档里藏得比较深,甚至没有直接的直白表述,但你的推断其实是完全正确的,而且能从R8的核心逻辑和官方给出的规则定义里得到佐证。
先给你拍板:keep规则确实会阻止-flattenpackagehierarchy和-repackageclasses(也就是你说的repackage)对目标类生效,原因如下:
- 从R8的处理阶段来看:官方明确过,
-flattenpackagehierarchy和-repackageclasses属于重命名(renaming)阶段的操作,它们的本质是修改类的包路径,属于类标识符重命名的一部分。而keep规则的核心作用就是保护指定类/成员不被重命名、缩减或移除——当你给某个类加上keep规则时,R8会完整保留它的限定类名(包括包名),自然不会对它执行包路径调整的操作。 - 从官方规则的定义细节推导:
官方对
keep规则的说明:Prevents the specified classes and class members from being removed or renamed.
这里的“renamed”并不仅限于类名本身,也包含包名的修改——毕竟类的完整限定名是包名+类名,属于同一标识符的组成部分。
官方对-flattenpackagehierarchy和-repackageclasses的说明:它们仅对“被重命名的类(renamed classes)”生效,而被keep规则保护的类不会进入重命名的队列,自然也就不会被执行包扁平化或重打包。
遗憾的是,目前官方文档确实没有专门用一个单独的条目来直接把这两者的关联写死,但从这些分散的规则定义和处理逻辑来看,你的理解完全没问题。如果你还想更确认,自己搭个小测试项目就能快速验证:写两个不同包的类,配置-flattenpackagehierarchy 'com.flattened',然后给其中一个类加-keep class com.original.package.MyClass,编译后看输出的类文件,被keep的类还在原包路径里,另一个则会被移到com.flattened下。
内容来源于stack exchange




