不需要混淆的场景如下,否则会出现运行错误:
1.如果使用了Gson之类的工具要使JavaBean类即实体类不被混淆。
2.如果使用了自定义控件那么要保证它们不参与混淆。
3.如果使用了枚举要保证枚举不被混淆。
4.对第三方库中的类不进行混淆
5.如果使用了Gson之类的工具要保证实体类不被混淆
6.如果使用了自定义控件那就需要保证它们不参与混淆
7.第三方库中的类不进行混淆
8.代码中使用了反射,需要保证该反射类类名方法不变
9.继承了Serializable接口的类不混淆
10.在引用第三方库的时候,一般会标明库的混淆规则的,建议在使用的时候就把混淆规则添加上去,免得到最后才去找
11.有用到 WebView 的 JS 调用也需要保证写的接口方法不混淆
12.Parcelable 的子类和 Creator 静态成员变量不混淆,否则会产生 Android.os.BadParcelableException 异常
13.Android四大组件和Application最好也不要混淆
ProGuard默认会对第三方库也进行混淆的,而第三方库有的已经混淆过了,有的使用了Java反射技术,所以我们在进行代码混淆的时候要排除这些第三方库。排除对第三方库的混淆需要在混淆规则文件(通常是:proguard-project.txt或proguard.cfg或proguard-rules.pro或proguard-rules.txt也可以是其它的文件名只要在配置文件中将含有混淆规则的文件名配置进去就行了)中添加如下规则:
具体需要保留keep的场景:
参考:https://www.cnblogs.com/cr330326/p/5534915.html
# 保留所有的本地native方法不被混淆
-keepclasseswithmembernames class * {
native ;
}
# 保留了继承自Activity、Application这些类的子类
# 因为这些子类,都有可能被外部调用a
# 比如说,第一行就保证了所有Activity的子类不要被混淆
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class * extends android.view.View
-keep public class com.android.vending.licensing.ILicensingService
# 如果有引用android-support-v4.jar包,可以添加下面这行
-keep public class com.xxxx.app.ui.fragment.** {*;}
# 保留在Activity中的方法参数是view的方法,
# 从而我们在layout里面编写onClick就不会被影响
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
# 枚举类不能被混淆
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
# 保留自定义控件(继承自View)不被混淆
-keep public class * extends android.view.View {
*** get*();
void set*(***);
public (android.content.Context);
public (android.content.Context, android.util.AttributeSet);
public (android.content.Context, android.util.AttributeSet, int);
}
# 保留Parcelable序列化的类不被混淆
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
# 保留Serializable序列化的类不被混淆
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
# 对于R(资源)下的所有类及其方法,都不能被混淆
-keep class **.R$* {
*;
}
# 对于带有回调函数onXXEvent的,不能被混淆
-keepclassmembers class * {
void *(**On*Event);
}
另外一篇混淆规则编写:http://www.imgeek.org/article/825308232
1,jni方法不可混淆,因为这个方法需要和native方法保持一致;
-keepclasseswithmembernames class * { # 保持native方法不被混淆
native ;
}
2,反射用到的类不混淆(否则反射可能出现问题);
3,AndroidMainfest中的类不混淆,所以四大组件和Application的子类和Framework层下所有的类默认不会进行混淆。自定义的View默认也不会被混淆;所以像网上贴的很多排除自定义View,或四大组件被混淆的规则在Android Studio中是无需加入的;
4,与服务端交互时,使用GSON、fastjson等框架解析服务端数据时,所写的JSON对象类不混淆,否则无法将JSON解析成对应的对象;
5,使用第三方开源库或者引用其他第三方的SDK包时,如果有特别要求,也需要在混淆文件中加入对应的混淆规则;
6,有用到WebView的JS调用也需要保证写的接口方法不混淆,原因和第一条一样;
7,Parcelable的子类和Creator静态成员变量不混淆,否则会产生Android.os.BadParcelableException异常;
-keep class * implements Android.os.Parcelable { # 保持Parcelable不被混淆
public static final Android.os.Parcelable$Creator *;
}
8,使用enum类型时需要注意避免以下两个方法混淆,因为enum类的特殊性,以下两个方法会被反射调用,见第二条规则。
-keepclassmembers enum * {
public static ** values();
public static ** valueOf(java.lang.String);
}
代码混淆后,也会导致Crash堆栈信息被混淆,难以阅读,增加定位问题位置的难度,一个混淆后的Crash堆栈信息类似这样,核心的信息都没了,
为了解决这个问题,可以使用
下的proguardgui.bat脚本将Crash堆栈信息还原到混淆前的状态。步骤如下:
- 双击打开脚本,选择左边的ReTrace选项
- 选择Mapping file文件,也就是混淆后打包后在
app module/build/outputs/mapping/release
下生成的mapping.txt
- 拷贝混淆后的堆栈信息
- 点击右下角的ReTrace!按钮,完成Crash堆栈信息的追溯
参考:
https://juejin.im/post/5a5c08ca6fb9a01ca47a7834
https://juejin.im/entry/5a4adacb51882538fe632107
比较有价值的相关文章整理:
https://medium.com/androiddevelopers/troubleshooting-proguard-issues-on-android-bce9de4f8a74 对应的译文:
https://juejin.im/post/5a5c08ca6fb9a01ca47a7834
Proguard用户手册:
https://www.guardsquare.com/en/products/proguard/manual/troubleshooting
配置学习:
https://juejin.im/entry/5a4adacb51882538fe632107
https://www.cnblogs.com/cr330326/p/5534915.html
http://www.imgeek.org/article/825308232