做Android项目,一旦要上线,一般都会用到混淆,不像ios,没有这个烦恼,现在就把我做这些项目遇到的坑总结下,便于后期自己查看,也顺便给大家做一个参考~~
下面是我混淆的一点小经验:
1.当res中有资源文件是动态使用时,不要在gradle里面将
shrinkResources 设置成true
shrinkResources true //移除无用的resource 文件
原因:因为这个属性会帮你移除项目中没用到的资源文件
解决经历:第一次碰到这个坑得时候搞了我好久,一直以为是混淆出错了,但却一直找不到原因,后来是有一天早上,灵光一现,想通了所有环节,发现最有可能出错的点,就是那里,后来改成false以后,果然一切正常
现象是:项目中有调用的图片都是正常的,没有调用的图片都变成小黑点,只有1kb
但如果你项目中没有动态设置的一些图片的时候,加上是比较好的,因为这样可以减小你的apk包的大小
2.一般调用第三方库混淆非常简单:
1》一般第三方库,网上都有相应的混淆配置
2》如果没有,也非常简单,直接忽略:
##eg:
-dontwarn org.androidannotations.**
-keep class org.androidannotations.** {*;}
##这样配置就可以
--dontwarn 第三方库包名
-keep class 第三方库包名.** {*;}
3》下面是根据官网,给出的一些基础配置:
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-printmapping priguardMapping.txt
-keepattributes SourceFile,LineNumberTable
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-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 com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
-keepclassmembers class **.R$* {
public static <fields>;
}
-dontwarn android.support.**
-keepnames class * implements java.io.Serializable
# 这指定了继承Serizalizable的类的如下成员不被移除混淆
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
!private <fields>;
!private <methods>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
# 保留自定义控件(继承自View)不能被混淆
-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
public void set*(***);
*** get* ();
}
4》自己的类的话,主要是实体类跟config,一般一个项目的实体类都放在同一个包下面,方便自己混淆,不遗漏
5》不能混淆的东西:
1.反射中使用的元素:如果一些被混淆使用的元素(属性,方法,类,包名等)进行了混淆,可能会出现问题,如NoSuchFiledException或者NoSuchMethodException等
2.GSON的序列化与反序列化
3.枚举也不要混淆
4.四大组件不建议混淆
Android中四大组件我们都很常用,这些组件不能被混淆的原因为
四大组件声明必须在manifest中注册,如果混淆后类名更改,而混淆后的类名没有在manifest注册,是不符合Android组件注册机制的.
外部程序可能使用组件的字符串类名,如果类名混淆,可能导致出现异常
5.注解不能混淆
6.其他不能混淆:
jni调用的java方法
java的native方法
js调用java的方法
第三方库不建议混淆
其他和反射相关的一些情况
参考博客:
http://droidyue.com/blog/2016/07/10/understanding-android-obfuscated-code-by-proguard/index.html
http://blog.csdn.net/zuiwuyuan/article/details/48552701
https://android.googlesource.com/platform/sdk/+/master/files/proguard-android-optimize.txt(标配)
总结:做项目,难免碰到一些难点,但是不要怕,当你真正沉浸在这件事中的时候,你总会找到解决方法!!只要相信:
世上无难事,只怕有心人!只要肯付出,别人能做的,咱也能做