一般Android项目,如果不想被反编译查看源码的话,这就需要我们去做一些安全措施;最基础的便是代码混淆。然而代码混淆并不能使程序绝对的安全,但是用来防止一些非专业的人足够了。
混淆处理的命令
1) 保持不混淆 -keep class 或 -keep public class xx.xx.类名,如
-keep public class * extends android.app.Activity
2
)第三方jar包引用 -libraryjars libs/xx.jar,如
-libraryjars libs/volley.jar
3
)忽略作用域下的警告 -dontwarn xx.xx.xx.类名,如
-dontwarn android.webkit.WebView
4
)忽略所有警告
-ignorewarnings
5
)保持类不被混淆,并指明作用域,如
-keep class com.umai.taok.manager.ClientAPI {
public *;
}
6
)保持类对象域不被混淆,如
-keepclassmembers class com.umai.taok.manager.ClientAPI {
public *;
}
混淆步骤
1) 对于android原生的类,不必做混淆处理
-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 * extends android.support.v4.**
-keep public class com.android.vending.licensing.ILicensingService
2) 对于第三方引用的jar包,需要声明
-libraryjars libs/xUtils-2.6.14.jar
-libraryjars libs/volley.jar
-libraryjars libs/umeng-analytics-v5.5.3.jar
-libraryjars libs/umeng_social_sdk.jar
-libraryjars libs/sun.misc.BASE64Decoder.jar
-libraryjars libs/SocialSDK_WeiXin_1.jar
-libraryjars libs/SocialSDK_WeiXin_2.jar
-libraryjars libs/SocialSDK_Sina.jar
-libraryjars libs/SocialSDK_QQZone_1.jar
-libraryjars libs/SocialSDK_QQZone_2.jar
-libraryjars libs/SocialSDK_QQZone_3.jar
-libraryjars libs/jpush-sdk-release1.8.1.jar
-libraryjars libs/httpmime-4.1.1.jar
-libraryjars libs/core-3.0.0.jar
-libraryjars libs/Android_Location_V1.3.2.jar
-libraryjars libs/Android_2DMapApi_V2.4.1.jar
-libraryjars libs/AMap_3DMap_V2.4.1.jar
3) 第三方的jar包源码,不必做混淆处理
-keep public class com.umeng.socialize.* {*;}
-keep class com.facebook.**
-keep class com.amap.api.mapcore.**{*;}
-keep class com.amap.api.maps.**{*;}
-keep class com.autonavi.amap.mapcore.*{*;}
-keep class cn.jpush.** { *; }
4)WebView相关的混淆处理
-keepclassmembers class com.umai.taok.manager.JSBridge$AndroidAPI {
public *;
}
-keepclassmembers class com.umai.taok.manager.ClientAPI {
public *;
}
-keep class com.umai.taok.manager.JSBridge$AndroidAPI {
public *;
}
-keep class com.umai.taok.manager.ClientAPI {
public *;
}
-dontwarn bolts.**
-keepattributes *Annotation*
-keepattributes *JavascriptInterface*
说明备注:
1、混淆配置的文件proguard-project.txt和project.properties。在
project.properties中系统已经添加了混淆文件的配置(#为注释符)。
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
将
project.properties中红色标注部分的注释放开即可。在proguard-project.txt中,我们可以进行混淆的添加。
2、不同的框架都提供了不同的混淆添加部分,这部分引用我们可以从开发平台copy到代码中。需要我们去添加的有三部分: (1) 第三方jar包的引用声明 (2)WebVIew的相关配置(说明见_3)(3)根据错误信息进行遗漏配置的补全以及警告隐藏
3、WebView的混淆需要进行配置,特别是webview与Js进行交互时,在混淆后有可能会失去效果。首先,我们需要先对进行Js交互的类进行保持处理,(由于我用JSBridge进行交互,所以需要两个Js接口类,如下
-keepclassmembers 包名.类名 { // 该类为Js调用方法的承载类
public *; // 公共方法
*; // 所有方法
}
-keepclassmembers class
包名.类名 {
public *;
}
如果Js调用方法的承载类为内部类,则需要如下添加
-keepclassmembers 包名.类名1$类名2 { // 类1 = 承载类的外部类,类2 = 承载类
public *; // 公共方法
*; // 所有方法
}
-keepclassmembers class
包名.类名1$类名2 {
public *;
}
在进行上述保持不混淆处理后,还需要添加以下配置
-keepattributes *Annotation*
-keepattributes *JavascriptInterface*
4、如果代码中使用了Facebook的Fresco框架,为了保证不混淆,需要添加如下配置
-keep class com.facebook.** { *; }
-dontwarn com.facebook.**
5、添加之后打包会出现些许的Bug,详见console. 我们可以根据Bug反馈进行进一步处理
1)如果出现找不到引用的情况,我们需要检查该引用是否被混淆,如果是,则需要添加保持
-keep class com.aps.** { *; }
2) 如果出现不必要的警告的提示,我们需要对这些警告设置忽略提示
-dontwarn com.aps.**
下面是我自己项目中用到的混淆配置策略:
# Add project specific ProGuard rules here. # By default, the flags in this file are appended to flags specified # in C:\Users\jasonxiao\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt # You can edit the include path and order by changing the proguardFiles # directive in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # Add any project specific keep options here: # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} -keepattributes SourceFile,LineNumberTable #不压缩输入的类文件 -dontshrink #指定代码的压缩级别 -optimizationpasses 5 #包明不混合大小写 -dontusemixedcaseclassnames #不去忽略非公共的库类 -dontskipnonpubliclibraryclasses #优化 不优化输入的类文件 -dontoptimize #预校验 -dontpreverify #混淆时是否记录日志 -verbose # 混淆时所采用的算法 -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* #保护注解 -keepattributes *Annotation* #忽略警告 -ignorewarnings -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 # 保持哪些类不被混淆 -keep public class com.google.vending.licensing.ILicensingService # 保持哪些类不被混淆 -keepclassmembers class **.R$* { public static <fields>; public static final int *; } -keepclasseswithmembernames class * { # 保持 native 方法不被混淆 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 * { # 保持枚举 enum 类不被混淆 public static **[] values(); public static ** valueOf(java.lang.String); } -keep class * implements android.os.Parcelable { # 保持 Parcelable 不被混淆 public static final android.os.Parcelable$Creator *; } -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*(...); } -keepclassmembers public class * extends android.view.View { void set*(***); *** get*(); } #apk 包内所有 class 的内部结构 #-dump class_files.txt #未混淆的类和成员 #-printseeds seeds.txt #列出从 apk 中删除的代码 #-printusage unused.txt #混淆前后的映射 #-printmapping mapping.txt #fastjson 可以混淆也可以不混淆 #-keep class javax.ws.rs.** { *; } #-dontwarn com.alibaba.fastjson.** #-keep class com.alibaba.fastjson.** { *; } -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(); public <fields>; } -keepattributes Signature #gson -dontwarn com.google.gson.** -keep class com.google.gson.** { *;} -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(); public <fields>; } #v4 -dontwarn android.support.v4.** -keep class android.support.v4.** { *; } -keep interface android.support.v4.app.** { *; } -keep public class * extends android.support.v4.** -keep public class * extends android.app.Fragment #greendao #-dontwarn de.greenrobot.dao.** #-keep class de.greenrobot.dao.** { *;} -keepclassmembers class * extends de.greenrobot.dao.AbstractDao { public static java.lang.String TABLENAME; } -keep class **$Properties #删除日志代码(标识无效代码) -assumenosideeffects class android.util.Log { public static boolean isLoggable(java.lang.String, int); public static int v(...); public static int i(...); public static int w(...); public static int d(...); public static int e(...); } #ACRA specifics # Restore some Source file names and restore approximate line numbers in the stack traces, # otherwise the stack traces are pretty useless -keepattributes SourceFile,LineNumberTable # ACRA needs "annotations" so add this... # Note: This may already be defined in the default "proguard-android-optimize.txt" # file in the SDK. If it is, then you don't need to duplicate it. See your # "project.properties" file to get the path to the default "proguard-android-optimize.txt". -keepattributes *Annotation* -dontwarn javax.annotation.** -dontwarn javax.inject.** -dontwarn sun.misc.Unsafe # Keep all the ACRA classes -keep class org.acra.** { *; } #okhttp # Don't warn about removed methods from AppCompat -dontwarn android.support.v4.app.NotificationCompat* #所有业务中的数据类不混淆(混淆后Gson无法解析) -keep class com.zhijiankeji.dlyw.index.** { *; } -keep class com.zhijiankeji.dlyw.common.** { *; } -keep class com.zhijiankeji.dlyw.ezviz.** { *; } -keep class com.zhijiankeji.dlyw.home.** { *; } -keep class com.zhijiankeji.dlyw.me.vo.** { *; } -keep class com.zhijiankeji.dlyw.index.** { *; } -keep class com.zhijiankeji.dlyw.vo.** { *; } -keep public class com.zhijiankeji.dlyw.common.BaseResponse { *; } -keep public class com.zhijiankeji.dlyw.common.BaseResponse.ErrorResponseEntity{ *; } #glide -keep class com.bumptech.glide.load.engine.**{*;} -keep public class * implements com.bumptech.glide.module.GlideModule -keep public class * extends com.bumptech.glide.AppGlideModule -keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** { **[] $VALUES; public *; } #alibaba -keepattributes InnerClasses -keep class com.alibaba.android.vlayout.ExposeLinearLayoutManagerEx { *; } -keep class android.support.v7.widget.RecyclerView$LayoutParams { *; } -keep class android.support.v7.widget.RecyclerView$ViewHolder { *; } -keep class android.support.v7.widget.ChildHelper { *; } -keep class android.support.v7.widget.RecyclerView$LayoutManager { *; } #android.support.v7 -dontwarn android.support.v7.** -keep class android.support.v7.** { *; } -keep interface android.support.v7.** { *; } #android-Ultra-Pull-To-Refresh -keep class in.srain.** { *; } #-dontwarn class in.srain.cube.image.ImageProvider #-dontwarn class android.graphics.Bitmap #-ignorewarnings class in.srain.cube.image.ImageProvider #-ignorewarnings class android.graphics.Bitmap ##---------------End: proguard configuration for Gson ---------- #guava -dontwarn com.google.common.base.** -keep class com.google.common.base.** {*;} -dontwarn com.google.errorprone.annotations.** -keep class com.google.errorprone.annotations.** {*;} -dontwarn com.google.j2objc.annotations.** -keep class com.google.j2objc.annotations.** { *; } -dontwarn java.lang.ClassValue -keep class java.lang.ClassValue { *; } -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement -keep class org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement { *; } -dontwarn okio.** -dontwarn okhttp3.** -dontwarn org.apache.mina.** -keep class org.apache.mina.**{*;} -dontwarn org.slf4j.** -dontwarn com.tencent.** -dontwarn com.alibaba.sdk.android.** -dontwarn com.baidu.location.** -keep class com.baidu.location.** {*;} -keep class com.baidu.lbsapi.** {*;} -keep class com.baidu.platform.** {*;} ##---------------Begin: proguard configuration for Retrofit ---------- # Platform calls Class.forName on types which do not exist on Android to determine platform. -dontnote retrofit2.Platform # Platform used when running on RoboVM on iOS. Will not be used at runtime. -dontnote retrofit2.Platform$IOS$MainThreadExecutor # Platform used when running on Java 8 VMs. Will not be used at runtime. -dontwarn retrofit2.Platform$Java8 # Retain generic type information for use by reflection by converters and adapters. -keepattributes Signature # Retain declared checked exceptions for use by a Proxy instance. -keepattributes Exceptions ##---------------End: proguard configuration for Retrofit -------- #支付宝代码混淆 -dontwarn android.net.** -keep class android.net.SSLCertificateSocketFactory{*;} -keep class com.alipay.android.app.IAlixPay{*;} -keep class com.alipay.android.app.IAlixPay$Stub{*;} -keep class com.alipay.android.app.IRemoteServiceCallback{*;} -keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;} -keep class com.alipay.sdk.app.PayTask{ public *;} -keep class com.alipay.sdk.app.AuthTask{ public *;} #EventBus混淆 -keepclassmembers class ** { @org.greenrobot.eventbus.Subscribe <methods>; } -keep enum org.greenrobot.eventbus.ThreadMode { *; } # Only required if you use AsyncExecutor -keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent { <init>(java.lang.Throwable); } #view子类代码不混淆 -keep class com.yuerbao.common.widget.**{*;} ###---------------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 # ## For using GSON @Expose annotation #-keepattributes *Annotation* # ## 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.** { *; } # ## Prevent proguard from stripping interface information from TypeAdapterFactory, ## JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter) #-keep class * implements com.google.gson.TypeAdapterFactory #-keep class * implements com.google.gson.JsonSerializer #-keep class * implements com.google.gson.JsonDeserializer # ###---------------End: proguard configuration for Gson ---------- ##---------------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 # For using GSON @Expose annotation -keepattributes *Annotation* # 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.** { *; } # Prevent proguard from stripping interface information from TypeAdapterFactory, # JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter) -keep class * implements com.google.gson.TypeAdapterFactory -keep class * implements com.google.gson.JsonSerializer -keep class * implements com.google.gson.JsonDeserializer -dontwarn com.ezviz.player.** -keep class com.ezviz.player.** { *;} -dontwarn com.ezviz.statistics.** -keep class com.ezviz.statistics.** { *;} -dontwarn com.ezviz.stream.** -keep class com.ezviz.stream.** { *;} -dontwarn com.hik.** -keep class com.hik.** { *;} -dontwarn com.hikvision.** -keep class com.hikvision.** { *;} -dontwarn com.videogo.** -keep class com.videogo.** { *;} -dontwarn com.videogo.** -keep class org.MediaPlayer.PlayM4.** { *;}
上述内容皆非原创,来自网络资料