代碼打包簽名
Android Studio為大家集成了代碼打包混淆的功能,具體操作流程如下組圖所示:
1、點擊Android Studio上方工具欄的 Build -> Generate Signed APK 選項,彈出如下右圖所示的對話框:
2、這里需要創建一個Key Store,如果你已經有了一個Key Store,那么Android Studio會讓你輸入密碼直接進行簽名打包;如果還沒有key Store,那么就點擊 Create New 按鈕去創建一個Key Store,如下圖:
3、在上圖所示的框中填入信息(基本上隨便填一個就行),后面幾個空可以不填,填完后點擊 OK 按鈕繼續,系統對Key Store進行保存后跳轉回到前一個對話框:
4、在對話框中填入剛才申請的Key Store的信息,點擊 Next 按鈕繼續,跳轉到下圖所示的對話框:
5、輸入剛才設置的密碼,點擊 OK 按鈕,跳轉到下面的對話框:
6、APK Destination Folder選擇的是Project或Module的路徑,Build Type是release。Flavors因為是我配置了MultiDex,因此會有兩個版本,保持默認就行,點擊Finish,Andorid Studio就會開始簽名打包,成功后會在右上角顯示一個提示框:
7、點擊 Show In Explorer 跳轉到文件目錄中,就可以看到剛才生成的APK文件了。
代碼混淆
代碼混淆是為了防止反編譯。如果沒有對APP進行代碼混淆,那么其他人很容易就可以得到你的APP中的所有代碼。而混淆之后,其他人就沒那么容易獲得了。
代碼混淆主要是在一個叫做 proguard-rules.pro 的文件中進行的,這個文件在Module目錄下。
要想設置代碼混淆,我們需要先配置項目,讓它支持混淆,方法是在主Module的build.gradle文件中將 minifyEnabled 設置為true即可,具體代碼如下:
android { compileSdkVersion 24 buildToolsVersion "24.0.2" defaultConfig { applicationId "com.example.itgungnir.testmultidex" minSdkVersion 11 targetSdkVersion 24 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled true // 設置代碼混淆 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:24.2.1' testCompile 'junit:junit:4.12' }
設置了代碼混淆,接下來就是在 proguard-rules.pro 文件中添加混淆的代碼了。
為了便於以后的參考,我在這里將一部分不是很常修改的代碼貼出來,每次需要混淆的時候只需要將這些代碼復制到 proguard-rules.pro 文件中即可:
-optimizationpasses 5 # 指定代碼的壓縮級別 -dontusemixedcaseclassnames # 是否使用大小寫混合 -dontpreverify # 混淆時是否做預校驗 -verbose # 混淆時是否記錄日志 -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 # 保持 native 方法不被混淆 -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); } # 保持自定義控件類不被混淆 -keepclassmembers class * extends android.app.Activity { public void *(android.view.View); } # 保持枚舉 enum 類不被混淆 -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); } # 保持 Parcelable 不被混淆 -keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; }
以下是一些常見的框架的混淆代碼:
Retrofit的混淆代碼:
# Retrofit 混淆代碼 -dontwarn retrofit.** -keep class retrofit.** { *; } -keepattributes Signature -keepattributes Exceptions
RxJava的混淆代碼:
# RxJava 混淆代碼 -dontwarn sun.misc.** -keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* { long producerIndex; long consumerIndex; } -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef { rx.internal.util.atomic.LinkedQueueNode producerNode; } -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef { rx.internal.util.atomic.LinkedQueueNode consumerNode; }
ButterKnife的混淆代碼:
# ButterKnife 混淆代碼 -keep class butterknife.** { *; } -dontwarn butterknife.internal.** -keep class **$$ViewBinder { *; } -keepclasseswithmembernames class * { @butterknife.* <fields>; } -keepclasseswithmembernames class * { @butterknife.* <methods>; }
Glide的混淆代碼:
# Glide 混淆代碼 -keep public class * implements com.bumptech.glide.module.GlideModule -keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** { **[] $VALUES; public *; }
EventBus的混淆代碼:
# EventBus 混淆代碼 -keepattributes *Annotation* -keepclassmembers class ** { @org.greenrobot.eventbus.Subscribe <methods>; } -keep enum org.greenrobot.eventbus.ThreadMode { *; } -keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent { <init>(java.lang.Throwable); }
ORMLite的混淆代碼:
# OrmLite 混淆代碼 -keep class com.j256.** -keepclassmembers class com.j256.** { *; } -keep enum com.j256.** -keepclassmembers enum com.j256.** { *; } -keep interface com.j256.** -keepclassmembers interface com.j256.** { *; } -keepattributes *Annotation* -keepclassmembers class * { @com.j256.ormlite.field.DatabaseField *; }
GreenDao的混淆代碼:
# GreenDao 混淆代碼 -keepclassmembers class * extends org.greenrobot.greendao.AbstractDao { public static java.lang.String TABLENAME; } -keep class **$Properties # If you do not use SQLCipher: -dontwarn org.greenrobot.greendao.database.** # If you do not use Rx: -dontwarn rx.**
FastJson的混淆代碼:
# FastJson 混淆代碼 -dontwarn com.alibaba.fastjson.** -keep class com.alibaba.fastjson.** { *; } -keepattributes Signature -keepattributes *Annotation*
Fresco的混淆代碼:
# Fresco 混淆代碼 -keep class com.facebook.fresco.** {*;} -keep interface com.facebook.fresco.** {*;} -keep enum com.facebook.fresco.** {*;}
OkHttp的混淆代碼:
# OkHttp 混淆代碼 -dontwarn com.squareup.okhttp3.** -keep class com.squareup.okhttp3.** { *;} -dontwarn okio.** # Okio -dontwarn com.squareup.** -dontwarn okio.** -keep public class org.codehaus.* { *; } -keep public class java.nio.* { *; }
其他混淆代碼請移步:【其他混淆代碼】