Androidstudio代码混淆其实很简单,但是由于没有大神指点,一个人自己百度摸索,还是恶心了好久好久
由于我现在的项目很小,所以混淆起来还是比较简单,一下我的步骤有些地方可能有些不太正确,请大神批评指点,小弟甘愿受领。
步骤:
1.再项目的app目录下的gradle文件中,修改buildTypes节点,修改的代码如下:
buildTypes { release { minifyEnabled true 开启混淆 shrinkResources true 打包时过滤无用的资源文件等 zipAlignEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } }
然后在项目的proguard-rules.pro文件中写自己的一些规则,我的如下(好多我也是从网上查询的)注释很清楚,自己看:
#指定代码的压缩级别 -optimizationpasses 5 #包明不混合大小写 -dontusemixedcaseclassnames #不去忽略非公共的库类 -dontskipnonpubliclibraryclasses #优化 不优化输入的类文件 -dontoptimize #预校验 -dontpreverify #混淆时是否记录日志 -verbose # 混淆时所采用的算法 -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* #保护注解 -keepattributes *Annotation* # 保持哪些类不被混淆 -keep public class * extends android.app.Fragment -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 #如果有引用v4包可以添加下面这行 -keep public class * extends android.support.v4.app.Fragment #忽略警告 -ignorewarning #####################记录生成的日志数据,gradle build时在本项目根目录输出################ #apk 包内所有 class 的内部结构 -dump class_files.txt #未混淆的类和成员 -printseeds seeds.txt #列出从 apk 中删除的代码 -printusage unused.txt #混淆前后的映射 -printmapping mapping.txt #应用了v4 v7包 -dontwarn android.support.** -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*(...); } #保持 native 方法不被混淆 -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); } #保持 Parcelable 不被混淆 -keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; } #保持 Serializable 不被混淆 -keepnames class * implements java.io.Serializable #保持 Serializable 不被混淆并且enum 类也不被混淆 -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(); } #保持枚举 enum 类不被混淆 如果混淆报错,建议直接使用上面的 -keepclassmembers class * implements java.io.Serializable即可 #-keepclassmembers enum * { # public static **[] values(); # public static ** valueOf(java.lang.String); #} -keepclassmembers class * { public void *ButtonClicked(android.view.View); } #不混淆资源类 -keepclassmembers class **.R$* { public static <fields>; } #第三方类库 不混淆第三方类库 -dontwarn com.hp.hpl.sparta.** #去除警告 -keep class com.hp.hpl.sparta.**{*;}#不被混淆 -dontwarn demo.** -keep class demo.**{*;} -dontwarn net.sourceforge.pinyin4j.** -keep class net.sourceforge.pinyin4j.**{*;} -dontwarn com.nostra13.universalimageloader.** -keep class com.nostra13.universalimageloader.**{*;} -dontwarn vivolibrary.** -keep class vivolibrary.**{*;} #-dontwarn com.android.volley.** #-dontwarn com.android.volley.jar.** #-keep class com.android.volley.**{*;} #-keep class com.android.volley.toolbox.**{*;} -dontwarn com.android.volley.** -keep class com.android.volley.** {*;} ##---------------Begin: proguard configuration for Gson ---------- # Gson uses generic type information stored in a class file when working with fields. Proguard # removes such information by default, so configure it to keep all of it. -keepattributes Signature # Gson specific classes -keep class com.google.** {*;} #-keep class com.google.gson.stream.** { *; } # Application classes that will be serialized/deserialized over Gson -keep class com.google.gson.examples.android.model.** { *; } ##这里需要改成解析到哪个 javabean -keep class com.google.gson.stream.** { *; } -keep class com.hzjiteng.call.model.**{*;} #让gson要解析成的javabean不被混淆
在混淆的时候我的apk一运行就报空指针异常,我也在Android开发的群里问了大神,由于我的网络框架请求用的是volley,大神一看到我的错误就直接定位于我的volley混淆不正确,然后对我各种指导,让我这小菜鸟备受感动,但是最终还是没在大神的指点下完成。无奈,只能找到报错的java文件,用log一句一句的输出检查(由于混淆了,所以全部是a,b,c的我也不知道哪里报错,只能知道是哪个java文件出错)。最后独自加班到很久终于找到错误,原来是我用了gson解析,解析生成的java类为空,才知道gson解析成的类不能混淆,虽然网上也有很多这样说的,但是一直以为是volley混淆出错,走了很多弯路。
以上混淆有很多不足的地方,我会再改进。
我的错误日志: