Proguard 删除 Android 应用程序中的注释

Posted

技术标签:

【中文标题】Proguard 删除 Android 应用程序中的注释【英文标题】:Proguard removing annotations in Android application 【发布时间】:2015-07-16 16:29:06 【问题描述】:

我在我的应用中包含了一个使用 gradle 的项目:

compile group: 'org.bytedeco', name: 'javacv', version: '0.11'

构建良好。但是,每当我在启用 proguard 的情况下运行应用程序时,它显然会从随后包含的 jar 中删除 @Platform 注释。

我尝试使用以下基于http://proguard.sourceforge.net/manual/examples.html#annotations

-keepattributes *Annotation*

-keep @org.bytedeco.javacpp.annotation interface * 
    *;

我还根据http://proguard.sourceforge.net/manual/troubleshooting.html#notkept尝试了以下

-keep @interface *

但这也不起作用。我还能尝试什么来阻止 proguard 删除这些注释?我在考虑使用 -injars-libraryjars 但我相信 gradle 会为你处理。


解决办法:

所以解决方法如下:

我的 proguard 规则中包含以下内容:

# JavaCV
-keep @org.bytedeco.javacpp.annotation interface * 
    *;


-keep @org.bytedeco.javacpp.annotation.Platform public class *

-keepclasseswithmembernames class * 
    @org.bytedeco.* <fields>;


-keepclasseswithmembernames class * 
    @org.bytedeco.* <methods>;


-keepattributes EnclosingMethod
-keep @interface org.bytedeco.javacpp.annotation.*,javax.inject.*

-keepattributes *Annotation*, Exceptions, Signature, Deprecated, SourceFile, SourceDir, LineNumberTable, LocalVariableTable, LocalVariableTypeTable, Synthetic, EnclosingMethod, RuntimeVisibleAnnotations, RuntimeInvisibleAnnotations, RuntimeVisibleParameterAnnotations, RuntimeInvisibleParameterAnnotations, AnnotationDefault, InnerClasses
-keep class org.bytedeco.javacpp.** *;
-dontwarn java.awt.**
-dontwarn org.bytedeco.javacv.**
-dontwarn org.bytedeco.javacpp.**

# end javacv

以及我的 gradle 中的以下几行(这些是日期为 7/5/2015 (dd/mm/yyyy) 的最新版本):

compile group: 'org.bytedeco', name: 'javacv', version: '0.11'
compile group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '2.4.11-0.11', classifier: 'android-arm'
compile group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '2.4.11-0.11', classifier: 'android-x86'
compile group: 'org.bytedeco.javacpp-presets', name: 'ffmpeg', version: '2.6.1-0.11', classifier: 'android-arm'
compile group: 'org.bytedeco.javacpp-presets', name: 'ffmpeg', version: '2.6.1-0.11', classifier: 'android-x86'

我很确定有些 proguard 规则有点矫枉过正,但我​​还没有测试过哪些是多余的。如果遇到此问题,您可能需要自己解决。

【问题讨论】:

你使用的是哪个 proguard 版本 @apk,我有最新版本的 AS 附带的版本。它是 proguard 4.7 版 请不要编辑您的问题以包含解决方案,而是将其发布为答案(您可以发布自己问题的答案)。 不,我和 Edson 在聊天中进行了讨论,他不得不离开。由于他在 0.10 版本上运行,而我在 0.11 版本上运行,这需要不同的 gradle 语句,而且他离线的脸让我在帖子中恢复了我的答案。他确实回答了这个问题,因此我接受了这个答案并分配了赏金。为方便起见,我将它添加到我的帖子中,因为我遇到了让它保持最新的麻烦。我认为这是一件令人愉快的事情。 【参考方案1】:

我也在使用 javacv,这是我的 proguard 文件的外观:

## JavaCV
-keepattributes *Annotation*, Exceptions, Signature, Deprecated, SourceFile, SourceDir, LineNumberTable, LocalVariableTable, LocalVariableTypeTable, Synthetic, EnclosingMethod, RuntimeVisibleAnnotations, RuntimeInvisibleAnnotations, RuntimeVisibleParameterAnnotations, RuntimeInvisibleParameterAnnotations, AnnotationDefault, InnerClasses
-keep class org.bytedeco.javacpp.** *;
-dontwarn java.awt.**
-dontwarn org.bytedeco.javacv.**
-dontwarn org.bytedeco.javacpp.**

这可能有点过分,但它最终使它对我有用。希望对你有帮助。

如果您将以下行添加到您的 gradle 文件中,您也不需要添加任何额外的 jar 文件:

compile group: 'org.bytedeco.javacpp-presets', name: <module>, version: <module-version>, classifier: <your-platform>

要获取可用模块,请在 jcenter 中搜索 javacpp,您将看到它们为 org.bytedeco.javacv-presets:&lt;module&gt;

单击其中任何一个都可以让您获得与您的 javacv 版本匹配的版本。因此,如果您使用 javacv 0.11 并想添加 opencv 模块,则需要使用 2.4.11-0.11 版本的 javacpp-preset。

最后,只需添加您选择的平台android-armandroid-x86 或两者兼而有之,您应该一切顺利。

最后,作为一个例子,下面是对于 arm 平台的 opencv 和 ffmpeg 的 javacv 导入:

compile group: 'org.bytedeco', name: 'javacv', version: '0.11'
compile group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '2.4.11-0.11', classifier: 'android-arm'
compile group: 'org.bytedeco.javacpp-presets', name: 'ffmpeg', version: '2.6.1-0.11', classifier: 'android-arm'

【讨论】:

嗯我现在得到一个不同的错误,关于丢失 .so 文件。你添加了额外的罐子吗?如果我这样做,我会在 Proguard 中收到重复的 zip 警告 你添加了本地人的 perst 文件吗?如果没有,则需要在 gradle 文件中添加以下行: compile group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '2.4.10-0.10', classifier: 'your_platform' compile组:'org.bytedeco.javacpp-presets',名称:'ffmpeg',版本:'2.5.1-0.10',分类器:'your_platform' 所以你不包括任何额外的罐子? 不,这些行已经为您完成了这项工作......只需尝试获取它们的最新版本。我仍在使用 0.10,但我确定有适用于 0.11 的预设 只是另一件事,所以它不会让人困惑。将“your_platform”替换为“android-arm”或“android-x86”,具体取决于您使用的内容,或者根据您想要支持的硬件类型为它们添加行。【参考方案2】:

也许这会有所帮助。

-keep @org.bytedeco.javacpp.annotation.Platform public class *

-keepclasseswithmembernames class * 
    @org.bytedeco.* <fields>;


-keepclasseswithmembernames class * 
    @org.bytedeco.* <methods>;

【讨论】:

【参考方案3】:

以下内容可能会有所帮助:

-keepattributes *Annotation*
-keepattributes EnclosingMethod
-keep @interface org.bytedeco.javacpp.annotation.*,javax.inject.*

【讨论】:

我已经尝试过您的建议,但很遗憾,它没有奏效。 对于丢失的 .so 文件,请记住跳过本机调用,如下所示:-keepclasseswithmembernames,includedescriptorclasses class * native &lt;methods&gt;; 【参考方案4】:

你可以使用:

-keepattributes *Annotation*

-keep @org.bytedeco.javacpp.annotation.Platform interface * 
    *;

-keepclassmembers,allowobfuscation class * 
    @org.bytedeco.javacpp.annotation.Platform <fields>;
    @org.bytedeco.javacpp.annotation.Platform <init>(...);

【讨论】:

以上是关于Proguard 删除 Android 应用程序中的注释的主要内容,如果未能解决你的问题,请参考以下文章

无法从 R8 配置中删除“-ignorewarnings”(Android Proguard 问题)

Android Proguard 未删除所有日志消息

使用 ProGuard 在 Android 中删除 LibGDX 日志

Android Proguard,删除所有Log语句并合并包

Android Jack 编译器没有从 proguard 规则中删除日志

android中的proguard和R