Android App程式碼混淆終極解決方案

Songlcy發表於2016-06-28

App雖然沒有那麼的高大上,但是程式碼的混淆是代表了程式設計師對App的責任心, 也是對App安全的一點點保證。今天我會將自己做Android混淆的過程和體會分享給大家,也避免大家少走彎路,少跳坑。

本篇部落格混淆基於Android Studio的IDE開發環境。

其實在Android Studio中做混淆,基本就是對Proguard-rules.pro檔案的操作。混淆的過程也是有規律可循的。下面我將分幾個部分來分別介紹混淆過程。

(1)如何開啟混淆。

(2)混淆的公共部分。

(3)需要我們不混淆的程式碼。

(4)libs下的第三方Jar包的混淆方式。

(5)complie的第三方Jar包的混淆方式。

(6)程式碼註釋的混淆方式。

ok,大家準備好了嗎?下面我就以流水賬的方式與大家分別介紹啦!(O(∩_∩)O 哈哈~)

1.如何開啟混淆

開始混淆很簡單,Android Studio中找到你的專案module的build.gradle,如下圖所示:


將minifyEnabled設定為true就ok。

2.公共部分

在混淆的過程中,有一部分是固定不變的。下面我將列出保持不變的模組,只需將程式碼Copy即可。

#1.基本指令區
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontpreverify
-verbose
-ignorewarning
-printmapping proguardMapping.txt
-optimizations !code/simplification/cast,!field/*,!class/merging/*
-keepattributes *Annotation*,InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable

#2.預設保留區
-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.view.View
-keep public class com.android.vending.licensing.ILicensingService
-keep class android.support.** {*;}

-keepclasseswithmembernames class * {
    native <methods>;
}
-keepclassmembers class * extends android.app.Activity{
    public void *(android.view.View);
}
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
-keep public class * extends android.view.View{
    *** get*();
    void set*(***);
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}
-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();
}
-keep class **.R$* {
 *;
}
-keepclassmembers class * {
    void *(**On*Event);
}

#3.webview
-keepclassmembers class fqcn.of.javascript.interface.for.webview {
   public *;
}
-keepclassmembers class * extends android.webkit.webViewClient {
    public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
    public boolean *(android.webkit.WebView, java.lang.String);
}
-keepclassmembers class * extends android.webkit.webViewClient {
    public void *(android.webkit.webView, jav.lang.String);
}

以上就是固定不變的部分。

3.需要我們不混淆的程式碼

不混淆用關鍵字-keep來修飾。不混淆的部分大概分為如下幾個模組:

(1)實體類,json解析類

(2)第三方jar包

(3)js和webview的呼叫模組

(4)與反射相關的類和方法

大概就是以上幾個模組,下面來看不混淆的程式碼:

#1.實體類
-keep class com.xx.xx.entity.** { *; }

#2.第三方包

#eventBus
-keepattributes *Annotation*
-keepclassmembers class ** {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.** { *; }
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    <init>(java.lang.Throwable);
}

#3.js互相呼叫的類
 沒有可不寫
#4.反射相關的類和方法
-keep class com.xx.xx.xx.xx.view.** { *; }
-keep class com.xx.xx.xx.xx.xx.** { *; }

4.libs下的第三方Jar包的混淆方式
保留libs下的jar包的方式也很簡單,同樣是使用-keep關鍵字:
找到libs目錄,開啟相對於的jar檔案,找到對應的包名,然後新增如下程式碼:
-keep class 包名.** { *; }
5.complie的第三方Jar包的混淆方式
complie的第三方Jar包的混淆方式和libs下的相同,只需要開啟:
開啟對應的引用jar檔案,然後同樣使用
-keep class 包名.** { *; }
6.程式碼註釋的混淆方式
我們在專案中肯定用到過有註釋方式的程式碼,例如小刀(butterknife)。需要使用@Bind來修飾變數。此時保留這種註釋需要如下程式碼:
這樣,就搞定啦!
以上就是Android混淆的全部內容了,希望大家細細品味!有問題的童靴可以給我留言,我會第一時間回覆!


相關文章