Android开发的都知道,项目不混淆很容易别反编辑出来。下面介绍下混淆代码的一般步骤。
1. 大家也许都注意到新建一个项目会创建一个app.gradle.开启混淆如下代码 minifyEnabled trues proguardFiles 混淆文件目录
buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.ast } debug { signingConfig signingConfigs.ast minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } }
新版Android studio会自动添加jar包混淆的,如果是老版本的请往下代码看
a. 把所有你的jar包都申明进来,代码 -libraryjars 例如:
-libraryjars libs/armeabi/libBaiduMapSDK_v2_3_1.so
-libraryjars libs/armeabi/liblocSDK4.so
-libraryjars libs/baidumapapi_v2_3_1.jar
-libraryjars libs/core.jar
-libraryjars libs/gesture-imageview.jar
-libraryjars libs/gson-2.0.jar
-libraryjars libs/locSDK_5.0.jar
b.混淆配置头部
#指定代码的压缩级别
-optimizationpasses 5
#包明不混合大小写
-dontusemixedcaseclassnames
#不去忽略非公共的库类
-dontskipnonpubliclibraryclasses
#优化 不优化输入的类文件
-dontoptimize
#预校验
-dontpreverify
#混淆时是否记录日志
-verbose
# 混淆时所采用的算法
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
#保护注解
-keepattributes *Annotation*
c. 将你不需要混淆的部分申明进来,因为有些类经过混淆会导致程序编译不通过,如下:
-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
--以上都是API里边的类,最好都要避免混淆
#如果有引用v4包可以添加下面这行
-keep public class * extends android.support.v4.app.Fragment
下面介绍几种比较常用需要混淆的代码
例如百度地图,你需要添加以下申明:
-keep class com.baidu.** { *; }
-keep class vi.com.gdi.bgl.android.**{*;}
一般model最好避免混淆(model无关紧要,不混淆也没多大关系)如:
-keep class com.bank.pingan.model.** { *; }
####混淆保护自己项目的部分代码以及引用的第三方jar包library-end####
-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);
}
#保持自定义控件类不被混淆
-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>;
}
#避免混淆泛型 如果混淆报错建议关掉
#–keepattributes Signature
#移除log 测试了下没有用还是建议自己定义一个开关控制是否输出日志
#-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(...);
#}
#如果用用到Gson解析包的,直接添加下面这几行就能成功混淆,不然会报错。
#gson
#-libraryjars libs/gson-2.2.2.jar
-keepattributes Signature
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
#如果用到注解框架butterknife
-dontwarn butterknife.internal.**
-keep class **$$ViewInjector { *; }
-keepnames class * { @butterknife.InjectView *;}
参数来保持第三方库中的类而不乱,-dontwarn和-keep 结合使用,意思是保持com.xx.bbb.**这个包里面的所有类和所有方法而不混淆,接着还叫ProGuard不要警告找不到com.xx.bbb.**这个包里面的类的相关引用。
-dontwarn com.xx.bbb.**
-keep class com.xx.bbb.** { *;}
加入新浪微博sdk遇到的问题
Proguard returned with error code 1. See console
Note: there were 1 duplicate class definitions.
Warning: library class android.webkit.WebViewClient depends on program class android.net.http.SslError
Warning: there were 1 instances of library classes depending on program classes.
You must avoid such dependencies, since the program classes will
be processed, while the library classes will remain unchanged.
java.io.IOException: Please correct the above warnings first.
at proguard.Initializer.execute(Initializer.java:321)
at proguard.ProGuard.initialize(ProGuard.java:211)
at proguard.ProGuard.execute(ProGuard.java:86)
at proguard.ProGuard.main(ProGuard.java:492)
根据异常相信同行们已经看出来了,还要单独keep 一下SslError这个,因为这个东西没有在 com.weibo.sdk.android这个包里面,于是再加上:
-dontwarn android.net.http.**
-keep class android.net.http .** { *;}对于引入了第三方Library,以actionbarsherlock为例
#actionbarsherlock start
-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }
-keep class com.actionbarsherlock.** { *; }
-keep interface com.actionbarsherlock.** { *; }
#actionbarsherlock start
so文件
-keep libs/arm64-v8a/libBaiduMapSDK_v3_5_0_31.so -keep libs/arm64-v8a/liblocSDK5.so -keep libs/armeabi/libBaiduMapSDK_v3_5_0_31.so -keep libs/armeabi/liblocSDK5.so -keep libs/armeabi-v7a/libBaiduMapSDK_v3_5_0_31.so -keep libs/armeabi-v7a/liblocSDK5.so
最后贴上自己项目的混淆文件。
# Add project specific ProGuard rules here. # By default, the flags in this file are appended to flags specified # in D:\sdk\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 *; #} #指定代码的压缩级别 -optimizationpasses 5 #包明不混合大小写 -dontusemixedcaseclassnames #不去忽略非公共的库类 -dontskipnonpubliclibraryclasses #优化 不优化输入的类文件 -dontoptimize #预校验 -dontpreverify #混淆时是否记录日志 -verbose #混淆时所采用的算法 -optimizations !code/simplification/arithmetic,!field/,!class/merging/ #保护注解 -keepattributes Annotation #取消警告 -dontwarn #忽略警告 -ignorewarning # 保持哪些类不被混淆 -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.** -keep public class * extends android.support.v4.app.Fragment #如果引用了v4或者v7包 -dontwarn android.support.** -keep class com.github.** { *; } -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 -keep class com.google.gson.examples.android.model.** { *; } -keep class com.alibaba.fastjson.** { *; } -dontwarn butterknife.internal.** -keep class **$$ViewInjector { *; } -keepnames class * { @butterknife.InjectView *;} -dontwarn com.facebook.** -dontwarn com.alipay.** -dontwarn org.apache.commons.net.** -dontwarn com.tencent.** #百度地图 -keep class com.baidu.** { *; } -keep class vi.com.gdi.bgl.android.**{*;} #根据我的经验,一般model最好避免混淆(model无关紧要,不混淆也没多大关系) -keep class com.bank.pingan.model.** { *; } #Gson混淆配置 -keepattributes *Annotation* -keep class sun.misc.Unsafe { *; } -keep class com.idea.fifaalarmclock.entity.*** -keep class com.google.gson.stream.** { *; } -dontwarn yundi.xx.bbb.** -keep class yundi.xx.bbb.** { *;} -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*(...); } -keep libs/arm64-v8a/libBaiduMapSDK_v3_5_0_31.so -keep libs/arm64-v8a/liblocSDK5.so -keep libs/armeabi/libBaiduMapSDK_v3_5_0_31.so -keep libs/armeabi/liblocSDK5.so -keep libs/armeabi-v7a/libBaiduMapSDK_v3_5_0_31.so -keep libs/armeabi-v7a/liblocSDK5.so