1.混淆规则,那些需要混淆,那些不进行混淆
2.混淆如何配置
3.混淆中遇到的问题

混淆是什么
简单说就是使用无意义的字符来替换原有的类名、方法名、字段名、参数名、变量名等。
为什么要混淆
如果不进行混淆,那么别人拿到你的apk去反编译下,别人就能根据你的代码完全写出一个跟你一样的apk。
如果你的是商业用途的app,那就跟脱光了衣服招摇过市一样了,危险性,大家自行脑补。
通过混淆也可以去除重复无用的代码,使代码的体积更小。
怎么进行代码混淆

Google 官网已经帮我们实现了一个通用的规则,但是一些特殊的规则需要自己去实现贴出来规则

-optimizationpasses 5                  # 指定代码的压缩级别
-dontusemixedcaseclassnames # 是否使用大小写混合
-dontobfuscate #不混淆输入的类文件
-dontpreverify # 混淆时是否做预校验
-verbose # 混淆时是否记录日志
-ignorewarnings # 忽略警告,避免打包时某些警告出现
-dontskipnonpubliclibraryclasses # 是否混淆第三方jar
-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 com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}

-dontwarn javax.servlet.**
-dontwarn org.joda.time.**
-dontwarn org.w3c.dom.**


-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}

但是往往一个app中会应用三方的SDK 或者jar包,这些也是不可以混淆的

总结一些不进行混淆内容

不混淆项目的常量

-keep class com.nuoyuan.sp2p.net.**{
*;
}

不混淆项目的常量

-keep class com.nuoyuan.sp2p.common.**{
*;
}

不混淆项目中的所有的Java Bean

-keep class com.nuoyuan.sp2p.bean.**{
*;
}

不混淆项目的自定义控件,因为会在项目的资源文件有引用

-keep class com.nuoyuan.sp2p.widget.**{
*;
}
Android官方建议不被混

-keep public class * implements java.io.Serializable
-keep public class * extends android.preference.Preference
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class com.android.vending.licensing.ILicensingServiceR文件

-keep public class com.nuoyuan.sp2p.R$*{
public static final int *;
}
不混淆本地的方法
-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);
}
不混淆项目中继承Activity的类,系统已经默认不会混淆继承Activity的类
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
不混淆项目中使用的枚举类
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
不混淆Java序列方法,系统序列化需要固定的方法
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}

混淆的好处

安全,缩小体积。

下面是友盟避免混淆的代码

-dontwarn com.umeng.**
-keep class com.umeng.**
-dontwarn com.tencent.**
-dontwarn com.facebook.**
-dontwarn android.webkit.WebView
-dontwarn com.tencent.weibo.sdk.**
-dontwarn org.apache.commons.net.**
-dontwarn com.google.android.maps.**

-keep enum com.facebook.**
-keep public class javax.**
-keep class com.facebook.**
-keep class com.umeng.scrshot.**
-keep public class android.webkit.**
-keep public class com.tencent.** {*;}
-keep public interface com.tencent.**
-keep public interface com.facebook.**
-keepattributes SourceFile,LineNumberTable
-keep class im.yixin.sdk.api.YXMessage {*;}
-keep class com.umeng.socialize.sensor.**
-keep public class com.umeng.socialize.* {*;}
-keep public interface com.umeng.scrshot.**
-keep public interface com.umeng.socialize.**
-keepattributes Exceptions,InnerClasses,Signature
-keep public interface com.umeng.socialize.sensor.**
-keep class com.tencent.mm.sdk.openapi.WXMediaMessage {*;}
-keep class im.yixin.sdk.api.** implements im.yixin.sdk.api.YXMessage$YXMessageData{*;}
-keep class com.tencent.mm.sdk.openapi.** implements com.tencent.mm.sdk.openapi.WXMediaMessage$IMediaObject {*;}

记得开启混淆开关:

buildTypes {
release {
minifyEnabled true //开关
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}

遇到的问题就是,同样的混淆效果不一样。看图

Android studio    代码混淆_facebook

正常混淆成功的应该明显看到这些 a~z 的字符。如果没有混淆的看不到这些(a~z).这个也不是一定。我们项目中混淆的代码少(这是混淆一些核心的代码)。看着和没有混淆过的代码一样。
还有一种判断是否进行混淆过,进行将apk包进行比较。混淆前后。包的体积会有变化。混淆过的代码体积小于混淆前的。(剔除了没有引用的代码)


给个demo:​​http://pan.baidu.com/s/1qYH15l6​


反编译工具:​​http://pan.baidu.com/s/1jHBrTqe​