使用 ProGuard 混淆私有字段
Posted
技术标签:
【中文标题】使用 ProGuard 混淆私有字段【英文标题】:Obfuscate private fields using ProGuard 【发布时间】:2015-08-12 02:51:30 【问题描述】:我在带有 Gradle 1.2.3 的 androidStudio 1.2.1.1 中使用 ProGuard。
我的 Gradle 的发布版本配置如下:
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
shrinkResources true
我希望对类的私有字段进行混淆处理。
这是我的 proguard 配置文件(经过多次尝试):
-allowaccessmodification
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
-repackageclasses ''
-verbose
[...]
但在使用 AndroidGuard 中的androdd
反编译后,我得到了:
private com.google.android.gms.common.api.GoogleApiClient googleApiClient;
我知道这种混淆的使用是有限的,但我希望 googleApiClient
被 ProGuard 重命名。该怎么做?
这里是refcard。
有什么办法可以和-keepclassmembernames
相反吗?
【问题讨论】:
googleApiClient 是唯一未混淆的字段还是所有字段都相同? 我希望所有私有字段都使用这个。 【参考方案1】:从中获得: How to tell ProGuard to keep private fields without specifying each field
根据ProGuard documenation,通配符匹配任何 字段。
最重要的是,您可以使用否定符 (!)。 (http://proguard.sourceforge.net/#manual/usage.html)
属性名称可以包含 ?、* 和 ** 通配符,它们可以是 前面有!否定句。
我在这个领域不是很有经验,所以这是一个猜测,但更容易写在新的评论中。像这样的东西应该可以完成这项工作(未测试):
-keepclassmembers class * //should find all classes
!private <fields>;
<methods>;
<init>; //and keep every field, method, constructor apart from private fields
也许你可以这样使用,但首先不确定它如何与否定符一起使用:
-keepclassmembers class * //should find all classes
!private <fields>;
*; //should exclude everything except private fields, which should be obfuscated.
【讨论】:
我使用了-keepclassmembers class my.package !private <fields>; protected <field>; public <fields>; <methods>;
并得到了我想要的:名称为a
、b
、c
等的字段。我知道这与否定者有关,感谢您将我带到正确使用。我会根据我的个人用途进行改进,但这就是我一直在寻找的答案。
这是我的最终 ProGuard 文件,可以运行 bug Android bug #78377:gist.github.com/shkschneider/a1c81780cd1f35a7037d
感谢您的回复和奖励!我很高兴您根据我的提示进行了锻炼,也感谢您提交到 github,这对我来说也是一次很好的体验。以上是关于使用 ProGuard 混淆私有字段的主要内容,如果未能解决你的问题,请参考以下文章
Proguard 混淆导致 java.lang.IllegalArgumentException:类声明多个名为“a”的 JSON 字段