混淆的一些事儿

Android studio写在proguard-rules.pro中,当然写在proguard-android.txt中也可以。
代码混淆,能够提高我们代码的安全性,打正式的release包混淆是必备的,避免APP被反编译,使项目中的技术泄漏。我们的APP加上混淆之后,即使被反编译了,别人也很难阅读,这就是混淆的好处。
此次项目中,做到分享的模块,用到了第三方的友盟分享。由于要更新友盟的SDK,在混淆配置后打包出现缺少jar包,翻了好久proguard-rules.pro文件最后发现,友盟统计的混淆配置中有许多不需要的jar文件配置,导致打包出错,下面说说Android的混淆机制:
一、
首先要在gradle文件中配置 minifyEnabled 为true ,在清单文件中加入(对release版本的混淆处理)
android {

buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile(‘proguard-android.txt’), ‘proguard-rules.pro’
}
}
}
项目代码混淆后越乱越无规律越好,但有些地方我们是要避免混淆的,否则程序运行就会出错,这就需要我们在proguard-rules.pro文件中配置那些代码不需要混淆,避免打包后出错。配置文件中常见的几个命令如:
-keep class org.apache.http.* {;}
-keep public class javax.**
-keep public class javax.*
第一种 既保持类名,又保持里面的内容不被混淆;
第二种 两颗星表示把本包和所含子包下的类名都保持;
第三种 一颗星表示只是保持该包下的类名,而子包下的类名还是会被混淆;
第二种,第三种类名不会变,但类里面的具体方法和变量名称还是会改变的。

如:
-keep public class * extends android.app.Activity
-keepnames class * implements java.io.Serializable
我们也可以使用Java的基本规则来保护特定类不被混淆,比如我们可以用extend,implement等这些Java规则来避免所有继承Activity的类被混淆

如:
-keep public class * extends android.view.View {
public (android.content.Context);
public (android.content.Context, android.util.AttributeSet);
public (android.content.Context, android.util.AttributeSet, int);
public void set*(…);
public ; //匹配所有构造器
public ; //匹配所有域
public ; //匹配所有方法方法
}
保护类下特定的内容不被混淆

如:
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
保持枚举类不被混淆
二、
以上整理关于配置混淆的一些注意事项
1、jni 方法不可混淆,因为要与native方法保持一致(有用到WebView的JS调用也需要保证写的接口方法不混淆)
具体配置
-keepclasseswithmembernames class * { # 保持native方法不被混淆 native ;
}
2、反射用到的类不混淆(枚举类因为需要反射机制,所以要避免枚举类被混淆)
3、AndroidMainfest中的类不混淆,所以四大组件和Application的子类和Framework层下所有的类默认不会进行混淆。自定义的View默认也不会被混淆;所以像网上贴的很多排除自定义View,或四大组件被混淆的规则在Android Studio中是无需加入的;
4、与服务端交互时,使用GSON、fastjson等框架解析服务端数据时,所写的JSON对象类不混淆,否则无法将JSON解析成对应的对象;
5、使用第三方开源库或者引用其他第三方的SDK包时,如果有特别要求,也需要在混淆文件中加入对应的混淆规则;
6、Parcelable的子类和Creator静态成员变量不混淆,否则会产生Android.os.BadParcelableException异常;
-keep class * implements Android.os.Parcelable { # 保持Parcelable不被混淆
public static final Android.os.Parcelable$Creator *;
}(序列化的另一种方式)

三、
附上一些第三方的混淆设置
Gson github地址

removes such information by default, so configure it to keep all of it.

-keepattributes Signature # Gson specific classes
-keep class sun.misc.Unsafe { ; } -keep class com.google.gson.stream.* { *; } # Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.* { ; } -keep class com.google.gson.* { ;} #这句非常重要,主要是滤掉 com.demo.demo.bean包下的所有.class文件不进行混淆编译,com.demo.demo是你的包名
-keep class com.demo.demo.bean.* {;}
Butterknife github地址
-keep class butterknife.* { ; } -dontwarn butterknife.internal.* -keep class *$$ViewBinder { ; } -keepclasseswithmembernames class { @butterknife.* ;
}
-keepclasseswithmembernames class * { @butterknife.* ;
}
SlidingMenu github地址
-dontwarn com.jeremyfeinstein.slidingmenu.lib.* -keep class com.jeremyfeinstein.slidingmenu.lib.*{*;}
ImageLoader github地址

Universal Image Loader

-keep class com.nostra13.universalimageloader.* { ; } -keepattributes Signature
ShareSDK 文档
-keep class cn.sharesdk.{;} -keep class com.sina.{;} -keep class .R ;keepclass.R;dontwarncn.sharesdk.dontwarn.R * -dontwarn com.tencent. -keep class com.tencent.* {;}
环信SDK 文档
-keep class com.easemob.* {;} -keep class org.jivesoftware.* {;} -keep class org.apache.* {;} -dontwarn com.easemob.** #2.0.9后的不需要加下面这个keep

-keep class org.xbill.DNS.* {;}

另外,demo中发送表情的时候使用到反射,需要keep SmileUtils

-keep class com.easemob.chatuidemo.utils.SmileUtils {*;} #注意前面的包名,如果把这个类复制到自己的项目底下,比如放在com.example.utils底下,应该这么写(实际要去掉#)

-keep class com.example.utils.SmileUtils {*;}

如果使用easeui库,需要这么写

-keep class com.easemob.easeui.utils.EaseSmileUtils {*;} #2.0.9后加入语音通话功能,如需使用此功能的api,加入以下keep
-dontwarn ch.imvs.* -dontwarn org.slf4j.* -keep class org.ice4j.* {;} -keep class net.java.sip.* {;} -keep class org.webrtc.voiceengine.* {;} -keep class org.bitlet.* {;} -keep class org.slf4j.* {;} -keep class ch.imvs.* {;}
Okhttputils github地址

okhttputils

-dontwarn com.zhy.http.* -keep class com.zhy.http.*{*;} #okhttp
-dontwarn okhttp3.* -keep class okhttp3.*{*;} #okio
-dontwarn okio.* -keep class okio.*{*;}
RxJava 相关文档

rx

-dontwarn rx.* -keepclassmembers class rx.* { *; } # retrolambda
-dontwarn java.lang.invoke.*
Glide github地址
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser** {   
  **[]
VALUES;
public *;
}

下面这句不加

-keepresourcexmlelements manifest/application/meta-data@value=GlideModule

再有用到的第三方可以查看第三方的SDK文档。

附上项目中基本的混淆 (命令)
-optimizationpasses 5 # 指定代码的压缩级别
-dontusemixedcaseclassnames # 是否使用大小写混合
-dontskipnonpubliclibraryclasses # 是否混淆第三方jar
-dontpreverify # 混淆时是否做预校验
-verbose # 混淆时是否记录日志
-optimizations !code/simplification/arithmetic,!field/,!class/merging/ # 混淆时所采用的算法
-ignorewarnings # 忽略警告
-printseeds seeds.txt #未混淆的类和成员
-printusage unused.txt #列出从 apk 中删除的代码
-printmapping mapping.txt #混淆前后的映射

-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 方法不被混淆
native ;
}

-keepclasseswithmembers class * { # 保持自定义控件类不被混淆
public (android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
public (android.content.Context, android.util.AttributeSet, int); # 保持自定义控件类不被混淆
}

-keepclassmembers class * extends android.app.Activity { # 保持自定义控件类不被混淆
public void *(android.view.View);
}

-keepclassmembers enum * { # 保持枚举 enum 类不被混淆
public static **[] values();
public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable { # 保持 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;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}

你可能感兴趣的:(问题汇总)