R8 在没有 -allowaccessmodification 标志的情况下将抽象类的“受保护”方法更改为“公共”

Posted

技术标签:

【中文标题】R8 在没有 -allowaccessmodification 标志的情况下将抽象类的“受保护”方法更改为“公共”【英文标题】:R8 changes "protected" methods of abstract class to "public" without -allowaccessmodification flag 【发布时间】:2020-04-28 02:39:12 【问题描述】:

我对 R8 有疑问。在MyLib 我有公共摘要MyLibsClass,其中我有受保护的方法。 MyChildClassMyApp 中的MyLibsClass 扩展,在R8 的魔法之后,MyLibsClass 中的所有受保护方法(包括受保护抽象)都更改为公共方法,当然在MyChildClass 我得到"attempting to assign weaker access privileges ('protected'); was 'public') 问题为试图覆盖受保护的抽象方法。

附加信息

gradle-6.0.1

MyLib 的 build.gradle

release 
    minifyEnabled true
    proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),'proguard-rules.pro'

proguard-rules.pro

-keep class com.example.mylib.*
    public protected *; 

-keep class com.example.mylib.*$*
    public protected *; 

有人遇到过这种问题或知道解决方法吗?

【问题讨论】:

【参考方案1】:

所以基于讨论here,

不要对库使用默认的 PROGUARD 设置

allowAccessModification 在默认的 proguard 设置中启用,它位于 Android SDK (\Android\Sdk\tools\proguard\proguard-android-optimize.txt) 中,我的错误是将它用于我的库。

来自proguard manual的引用

在处理要处理的代码时,您可能不应该使用此选项 用作库,因为类和类成员不是 设计为在 API 中公开的可能会变为公开。

因此,如果有人遇到同样的问题,我建议您为proguard 创建您自己的基本配置文件,并将没有"allowAccessModification" 的整个默认配置复制到其中。

另外,如果有人更感兴趣,您可以跟踪this 问题。希望能在近功能中为库获得单独的配置文件。

【讨论】:

【参考方案2】:

这也在 R8 错误跟踪器上报告,并在那里解决。见http://issuetracker.google.com/147447502。

【讨论】:

谢谢@sgjesse,其实我是记者:)。【参考方案3】:

我遇到了同样的问题,感谢@Hayk Nahapetyan 的回答,我可以解决它。

这是我的解决方案,其中包含更多细节。

在库模块的 build.gradle 中,从 buildTypesrelease 闭包中删除默认文件:

release 
    minifyEnabled true
    proguardFiles 'proguard-rules.pro'

R8 不再使用 Android SDK 中提供的默认文件。它在构建时生成一个,并将其放在模块的构建目录build/intermediates/default_proguard_files/global

proguard-android-optimize.txt-a.b.c 的内容(其中a.b.c 是库版本,如果已设置)从该位置复制到模块proguard-rules.pro 的顶部。然后删除-allowaccessmodification;两次,如果它最初出现在两个文件中。

【讨论】:

以上是关于R8 在没有 -allowaccessmodification 标志的情况下将抽象类的“受保护”方法更改为“公共”的主要内容,如果未能解决你的问题,请参考以下文章

ESP8266-01 与 NUCLEO-F030R8 通信

同时使用 ProGuard 和 R8

Proguard/R8 规则排除资产文件夹

Proguard (R8) 混淆自定义视图名称

x64dbg 中的“r8d”是啥?

Firebase + Proguard/R8