不論是商用APK還是個(gè)人開發(fā)的APK,一旦放在網(wǎng)絡(luò)上,都將面臨一個(gè)問(wèn)題:開發(fā)者辛辛苦苦開發(fā)的程序被他人反編譯,輕松獲取開發(fā)者的源代碼。如果對(duì)方僅僅只是拿來(lái)學(xué)習(xí),或許開發(fā)者會(huì)很樂意這樣;但是如果對(duì)方拿來(lái)危害開發(fā)者或者企業(yè)利益,甚至危害社會(huì)利益,那就是開發(fā)者所不愿意看到的了。
為了防止開發(fā)者代碼被輕易竊取,代碼混淆概念的引入也就應(yīng)運(yùn)而生了。百度百科上給 代碼混淆 的定義如下:
代碼混淆(Obfuscated code)亦稱花指令,是將計(jì)算機(jī)程序的代碼,轉(zhuǎn)換成一種功能上等價(jià),但是難于閱讀和理解的形式的行為。代碼混淆可以用于程序源代碼,也可以用于程序編譯而成的中間代碼。執(zhí)行代碼混淆的程序被稱作代碼混淆器。目前已經(jīng)存在許多種功能各異的代碼混淆器。
Google似乎也發(fā)現(xiàn)了反編譯的問(wèn)題,從SDK2.3開始我們可以看到在android-sdk-windows\tools\下面多了一個(gè)proguard文件夾。
ProGuard是一個(gè)免費(fèi)的Java類文件收縮,優(yōu)化,混淆和預(yù)校驗(yàn)器。它可以檢測(cè)并刪除未使用的類,字段,方法和屬性。它可以優(yōu)化字節(jié)碼,并刪除未使用的指令。它可以將類、字段和方法使用短無(wú)意義的名稱進(jìn)行重命名。最后,預(yù)校驗(yàn)的Java6或針對(duì)Java MicroEdition的所述處理后的碼。
**一、混淆的規(guī)則
**
ProGuard默認(rèn)會(huì)對(duì)第三方庫(kù)也進(jìn)行混淆的,而第三方庫(kù)有的已經(jīng)混淆過(guò)了,有的使用了Java反射技術(shù),
所以我們?cè)谶M(jìn)行代碼混淆的時(shí)候要排除這些第三方庫(kù)。排除對(duì)第三方庫(kù)的混淆需要在混淆規(guī)則文件(通
常是:proguard-project.txt或proguard.cfg或proguard-rules.pro或proguard-rules.txt也可以是其
它的文件名只要在配置文件中將含有混淆規(guī)則的文件名配置進(jìn)去就行了)中添加如下規(guī)則:
1.如果使用了Gson之類的工具要使JavaBean類即實(shí)體類不被混淆。
2.如果使用了自定義控件那么要保證它們不參與混淆。
3.如果使用了枚舉要保證枚舉不被混淆。
4.對(duì)第三方庫(kù)中的類不進(jìn)行混淆
a.混淆時(shí)保護(hù)引用的第三方j(luò)ar包
如:-libraryjars libs/baidumapapi_v3_2_0.jar #保護(hù)引用的第三方j(luò)ar包不被混淆
注意:在使用Eclipse+ADT時(shí)需要加入-libraryjars libs/...,如果你是使用Android Studio開發(fā)的項(xiàng)目則不需要加入libs包中的jar包,這是因?yàn)椋ㄟ^(guò)Android Studio進(jìn)行混淆代碼時(shí),默認(rèn)已經(jīng)將 lib目錄中的 jar 都已經(jīng)添加到打包腳本中,所以不需要再次手動(dòng)添加,否則會(huì)出現(xiàn)“ java.io.IOException: The same input jar is specified twice” 錯(cuò)誤。
b.混淆時(shí)保護(hù)第三方j(luò)ar包中的類不被混淆
如:-keep class com.baidu.** { ; } #讓ProGuard不要警告找不到com.baidu.這個(gè)包里面的類的相關(guān)引用
-dontwarn com.baidu.* #保持com.baidu.**這個(gè)包里面的所有類和所有方法不被混淆。
**二、開發(fā)工具為eclispe+sdk和開發(fā)工具為Android Studio兩種方式的介紹混淆。
**
1、開發(fā)工具為eclispe+sdk的混淆介紹
下面具體說(shuō)一說(shuō)怎么樣讓SDK2.3下的proguard.cfg文件起作用,先來(lái)看看android-sdk-windows\tools\lib*proguard.cfg*的內(nèi)容:
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-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
-keepclasseswithmembernames class * {
native <</span>methods>;
}
-keepclasseswithmembernames class * {
public <</span>init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public <</span>init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(;
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
從腳本中可以看到,混淆中保留了繼承自Activity、Service、Application、BroadcastReceiver、ContentProvider等基本組件以及com.android.vending.licensing.ILicensingService,
并保留了所有的Native變量名及類名,所有類中部分以設(shè)定了固定參數(shù)格式的構(gòu)造函數(shù),枚舉等等。(詳細(xì)信息請(qǐng)參考/examples中的例子及注釋。)
讓proguard.cfg起作用的做法很簡(jiǎn)單,就是在eclipse自動(dòng)生成的default.properties文件中加上一句“proguard.config=proguard.cfg”就可以了
完整的default.properties文件應(yīng)該如下:
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=android-9
proguard.config=proguard.cfg
大功告成,正常的編譯簽名后就可以防止代碼被反編譯了。反編譯經(jīng)過(guò)代碼混淆的apk得到的代碼應(yīng)該類似于下面的效果,是很難看懂的:

如果您使用的是2.3之前的SDK版本也沒關(guān)系,把上面的proguard.cfg文件復(fù)制一份放到項(xiàng)目中,然后進(jìn)行相同的操作即可。
2、開發(fā)工具為****Android Studio****的混淆介紹
使用Android Studio工具中,將混淆文件的存放路徑為:項(xiàng)目所在文件夾路徑\app\proguard-rules.pro,其中proguard-rules.pro名字是由gradle配置文件指定的,接下來(lái)介紹gradle配置文件中設(shè)置混淆。
在gradle下的配置文件信息為:
buildTypes {
release {
signingConfig signingConfigs.release //設(shè)置簽名信息
minifyEnabled false //true表示開啟混淆,false表示關(guān)閉混淆
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆規(guī)則文件名
}
debug {
signingConfig signingConfigs.debug
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
只要在文件proguard-rules.pro中設(shè)置符合混淆規(guī)則,就可以輕松的完成混淆,是不是很簡(jiǎn)單呢?
我列舉下我用過(guò)或者見過(guò)的混淆設(shè)置給大家借鑒,希望對(duì)各位有幫助:

