代碼混淆詳解

什麼是代碼混淆

保留內部類不被混淆
-keepnames class com.AnywayAds.Mini$* {
    public <fields>;
    public <methods>;
}

或者

-keep class com.brutegame.hongniang.EventMemberListActivity$EventMemberListFragment$Page* { *; }//EventMemberListActivity中的EventMemberListFragment類中的Page類的方法和屬性都不混淆

Java 是一種跨平臺的、解釋型語言,Java 源代碼編譯成中間”字節碼”存儲於 class 文件中。由於跨平臺的需要,Java 字節碼中包括了很多源代碼信息,如變量名、方法名,並且通過這些名稱來訪問變量和方法,這些符號帶有許多語義信息,很容易被反編譯成 Java 源代碼。爲了防止這種現象,我們可以使用 Java 混淆器對 Java 字節碼進行混淆。

混淆就是對發佈出去的程序進行重新組織和處理,使得處理後的代碼與處理前代碼完成相同的功能,而混淆後的代碼很難被反編譯,即使反編譯成功也很難得出程序的真正語義。被混淆過的程序代碼,仍然遵照原來的檔案格式和指令集,執行結果也與混淆前一樣,只是混淆器將代碼中的所有變量、函數、類的名稱變爲簡短的英文字母代號,在缺乏相應的函數名和程序註釋的況下,即使被反編譯,也將難以閱讀。同時混淆是不可逆的,在混淆的過程中一些不影響正常運行的信息將永久丟失,這些信息的丟失使程序變得更加難以理解。

混淆器的作用不僅僅是保護代碼,它也有精簡編譯後程序大小的作用。由於以上介紹的縮短變量和函數名以及丟失部分信息的原因, 編譯後 jar 文件體積大約能減少25% ,這對當前費用較貴的無線網絡傳輸是有一定意義的。

混淆文件 proguard.cfg 參數詳解

[plain] view plain copy 在CODE上查看代碼片派生到我的代碼片
-optimizationpasses 5                                                           # 指定代碼的壓縮級別  
-dontusemixedcaseclassnames                                                     # 是否使用大小寫混合  
-dontskipnonpubliclibraryclasses                                                # 是否混淆第三方jar  
-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 方法不被混淆  
    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 class MyClass;                                                            # 保持自己定義的類不被混淆  


代碼混淆的方法

根據 SDK 的版本不同有 2 中不同的代碼混淆方式,以上的 proguard.cfg 參數詳解中所涉及到的信息是在較低版本 SDK 下的混淆腳本,事實上在高版本的 SDK 下混淆的原理和參數也與低版本的相差無幾,只是在不同 SDK 版本的環境下引入混淆腳本的方式有所不同。具體方法如下:

低版本 SDK 下,項目中同時包含 proguard.cfg 和 project.properties 文件,則只需在 project.properties 文件末尾添加 proguard.config=proguard.cfg 再將項目 Export 即可。
高版本 SDK 下,項目中同時包含 proguard-project.txt 和 project.properties 文件,這時需要在 proguard-project.txt 文件中進行如下信息的配置,然後再將項目 Export 即可。下面以真實的文件進行演示說明。
複製代碼
# 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 edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

# Project target.
target=android-16
複製代碼
以上的配置信息即是 project.properties 文件中內容,藍色文字爲我們在代碼混淆過程中需要添加的配置信息,其中:sdk.dir 爲你在當前機器上 SDK 的安裝路徑。如果想保留某個包下的文件不被混淆,可以在 proguard-project.txt文件中加入保留對應包名的語句即可。

複製代碼
# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

-dontwarn com.cnki.android.cnkireader.** 
-keep class com.cnki.android.cnkireader.** { *; }

# 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


# 不預校驗
# -dontpreverify


# 預校驗
-dontoptimize 




# 這1句是屏蔽警告
-ignorewarnings 
-verbose


# 優化
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*


# 這1句是導入第三方的類庫,防止混淆時候讀取包內容出錯
#-libraryjars libs/youjar.jar 


# 去掉警告
-dontwarn 
-dontskipnonpubliclibraryclassmembers


# 不進行混淆保持原樣
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Fragment 
-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




# 過濾R文件的混淆:
-keep class **.R$* {*;}


# 過濾第三方包的混淆:其中packagename爲第三方包的包名
# -keep class packagename.** {*;}
-keep class com.hisilicon.android.hibdinfo.** {*;}
-keep class com.huawei.iptv.stb.dlna.mymedia.dto.** {*;}
-keep class com.huawei.iptv.stb.dlna.mymedia.facade.** {*;}
-keep class com.huawei.mymediaprifacade.** {*;}
-keep class com.hisilicon.android.mediaplayer.** {*;}
-keep class com.nostra13.universalimageloader.** {*;}
-keep class com.huawei.android.airsharing.** {*;}


# 所有方法不進行混淆
-keep public abstract interface com.huawei.android.airsharing.listener{
public protected <methods>;
}


-keep public abstract interface com.huawei.android.airsharing.api{
public protected <methods>;
}


# 對該方法不進行混淆
# -keep public class com.asqw.android{
# public void Start(java.lang.String); 
# }


# 保護指定的類和類的成員的名稱,如果所有指定的類成員出席(在壓縮步驟之後)
#-keepclasseswithmembernames class * {
#    native <methods>;
#}


# 保護指定的類和類的成員,但條件是所有指定的類和類成員是要存在
#-keepclasseswithmembernames class * {
#    public <init>(android.content.Context, android.util.AttributeSet);
#}


-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}


# 保護指定類的成員,如果此類受到保護他們會保護的更好
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}




-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}


# 保護指定的類文件和類的成員
-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}


#-libraryjars libs/android-support-v4.jar
#-dontwarn android.support.v4.**{*;}


# 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 *;
}


#不混淆第三方包中的指定內容
-keep class android-support-v4.**{*;}
-keep public class * extends android.support.v4.**
-keep class android.view.**{*;}









ProGuard是一個免費的java類文件壓縮,優化,混淆器.它探測並刪除沒有使用的類,字段,方法和屬性.它刪除沒有用的說明並使用字節碼得到最大優化.它使用無意義的名字來重命名類,字段和方法.

ProGuard的使用是爲了:

1.創建緊湊的代碼文檔是爲了更快的網絡傳輸,快速裝載和更小的內存佔用.
2.創建的程序和程序庫很難使用反向工程.
3.所以它能刪除來自源文件中的沒有調用的代碼
4.充分利用java6的快速加載的優點來提前檢測和返回java6中存在的類文件.

參數:

-include {filename} 從給定的文件中讀取配置參數

-basedirectory {directoryname} 指定基礎目錄爲以後相對的檔案名稱

-injars {class_path} 指定要處理的應用程序jar,war,ear和目錄

-outjars {class_path} 指定處理完後要輸出的jar,war,ear和目錄的名稱

-libraryjars {classpath} 指定要處理的應用程序jar,war,ear和目錄所需要的程序庫文件

-dontskipnonpubliclibraryclasses 指定不去忽略非公共的庫類。

-dontskipnonpubliclibraryclassmembers 指定不去忽略包可見的庫類的成員。

保留選項
-keep {Modifier} {class_specification} 保護指定的類文件和類的成員

-keepclassmembers {modifier} {class_specification} 保護指定類的成員,如果此類受到保護他們會保護的更好

-keepclasseswithmembers {class_specification} 保護指定的類和類的成員,但條件是所有指定的類和類成員是要存在。

-keepnames {class_specification} 保護指定的類和類的成員的名稱(如果他們不會壓縮步驟中刪除)

-keepclassmembernames {class_specification} 保護指定的類的成員的名稱(如果他們不會壓縮步驟中刪除)

-keepclasseswithmembernames {class_specification} 保護指定的類和類的成員的名稱,如果所有指定的類成員出席(在壓縮步驟之後)

-printseeds {filename} 列出類和類的成員-keep選項的清單,標準輸出到給定的文件

壓縮
-dontshrink 不壓縮輸入的類文件

-printusage {filename}

-whyareyoukeeping {class_specification}

優化
-dontoptimize 不優化輸入的類文件

-assumenosideeffects {class_specification} 優化時假設指定的方法,沒有任何副作用

-allowaccessmodification 優化時允許訪問並修改有修飾符的類和類的成員

混淆
-dontobfuscate 不混淆輸入的類文件

-printmapping {filename}

-applymapping {filename} 重用映射增加混淆

-obfuscationdictionary {filename} 使用給定文件中的關鍵字作爲要混淆方法的名稱

-overloadaggressively 混淆時應用侵入式重載

-useuniqueclassmembernames 確定統一的混淆類的成員名稱來增加混淆

-flattenpackagehierarchy {package_name} 重新包裝所有重命名的包並放在給定的單一包中

-repackageclass {package_name} 重新包裝所有重命名的類文件中放在給定的單一包中

-dontusemixedcaseclassnames 混淆時不會產生形形色色的類名

-keepattributes {attribute_name,...} 保護給定的可選屬性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses.

-renamesourcefileattribute {string} 設置源文件中給定的字符串常量
因爲我們開發的是webwork+spring+hibernate的架構的項目,所有需要很詳細的配置。(經過n次失敗後總結)
Example:
-injars <project>.jar
-outjars <project>_out.jar
-libraryjars <java.home>/lib/rt.jar
-libraryjars <project.home>/webroot/WEB-INF/lib/webwork.jar
.......
# 保留實現Action接口類中的公有的,友好的,私有的屬性 和 公有的,友好的方法。其它的全部壓縮,優化,混淆。
# 因爲配置文件中的類名是一個完整的類名,如果經過處理後就有可能找不到這個類。
# 屬性是jsp頁面所需要的,如果經過處理jsp頁面就無法得到action中的數據。
-keep public class * implements com.opensymphony.xwork.Action{
public protected private <fields>;
public protected <methods>;
}
# 保留實現了Serializable接口類中的公有的,友好的,私有的成員(屬性和方法)
# 這個配置主要是對應實體類的配置。
-keep public class * implements java.io.Serializable{
public protected private *;
}


由於工作需要,這兩天和同事在研究android下面的ProGuard工具的使用,通過查看android官網對該工具的介紹以及網絡上其它相關資料,再加上自己的親手實踐,算是有了一個基本瞭解。下面將自己的理解和認識簡要的做個筆記,有異議或者不解的,可以直接留言。

什麼是ProGuard工具?

ProGuard是android提供的一個免費的工具,它能夠移除工程中一些沒用的代碼,或者使用語義上隱晦的名稱來重命名代碼中的類、字段和函數等,達到壓縮、優化和混淆代碼的功能。具體來說,使用ProGuard工具,可以達到下面兩個目的:

刪除了源文件中沒有調用的那部分代碼,最大化的精簡了字節碼文件,使得最終生成的apk文件更小。
使用語義混淆的命名替換了代碼中的類、字段和函數等,使得其他人無法反編譯獲取源代碼,起到對代碼的保護作用。
我看網上有不少人根據ProGuard工具的作用,直接稱呼其爲“混淆代碼工具”,本文也暫時用這個詞簡稱。

更多的理解,可以參考ProGuard工具的官方文檔地址:http://developer.android.com/tools/help/proguard.html

ProGuard工具的集成與使用環境

其實,ProGuard工具是已經集成到我們android系統中的,所以不需要用戶手動的去集成。但是有一點需要注意,僅在程序處於Release模式時ProGuard纔有效,反之在Debug模式是不能通過ProGuard來混淆代碼的。

根據ProGuard的具體使用環境,我分在Eclipse工具和android源碼兩種編譯環境淺談ProGuard的使用方法。

Eclipse環境中ProGuard的使用

以我電腦的android4.0環境爲例,當我們在Eclipse中新建一個項目,或者導入一個已存在項目(保證當前項目沒有語法錯誤)後,在工程的根目錄,會自動生成兩個ProGuard的混淆文件:proguard-project.txt和project.properties(在老版本的ADT中,只會生成一個叫proguard.cfg的文件)。我們先看下文件project.properties :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 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 edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

# Project target.
target=android-16
看後面一段註釋:To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home) ,意指要讓ProGuard 來壓縮和混淆代碼,把這句註釋去掉即可!所以,我們只要把下面一句註釋取消即可,如下所示:

1
2
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
我們仔細的看下這部分代碼:這個地方是通過設置proguard.config屬性來指定混淆代碼的配置文件爲本機SDK目錄下面的proguard-android.txt文件,以及制定混淆的個性化配置文件爲當前工程(eclipse下)根目錄下面的proguard-project.txt文件 ,而後面這個文件,恰是我們剛纔看到的原本在根目錄下自動生成的另外一個文件!

其實打開了這個地方,我們就已經可以混淆代碼了,不過這裏要注意:不能試圖通過運行eclipse中的Run as 和 Debug as 菜單來生成混淆代碼,必須通過如下圖所示的方法將apk導出才行,當然你可以選擇“簽名”或者“不簽名”:

圖片說明文字

這樣一步操作後,算是代碼混淆完成了。那麼怎麼才能檢驗我們真的混淆了代碼了呢?首先,我們能夠看到在工程的根目錄新生產了一個文件夾proguard,裏面有四個文件,其內容如下:

dump.txt : 描述了apk中所有類 文件中內部的結構體。( Describes the internal structure of all the class files in the .apk file )
mapping.txt : 列出了原始的類、方法和名稱與混淆代碼見得映射。( Lists the mapping between the original and obfuscated class, method, and field names. )
seeds.txt : 列出了沒有混淆的類和方法。( Lists the classes and members that are not obfuscated )
usage.txt : 列出congapk中刪除的代碼。( Lists the code that was stripped from the .apk )
同時使用反編譯軟件對新生成的apk反編譯後會發現,裏面的類名、方法和變量等,都變成了簡單的a、b、c、d等毫無含義的字母,這樣就達到了混淆的目的:
圖片說明文字

但在實際使用過程中,我們會發現當前apk中的有些方法和類,是要供外部使用的,而此時混淆了名稱,外部調用就會報錯了,那麼怎麼解決這個問題?此時就要用到我們剛纔提到的混淆的個性化配置文件proguard-project.txt,在其中去配置不需要混淆的類、方法和變量等。關於混淆文件的具體配置方法,請看下面的最後一個標題會有詳述。

Android源碼環境中ProGuard使用

在Google發佈的android源碼中,面對那麼多代碼和文件目錄,此時該如何混淆代碼與配置混淆文件呢?

android中默認是將代碼混淆ProGuard關閉的,在alps/build/core/proguard.flags中有下面一句,意指將默認不混淆,不需要代碼刪除,我們將這一句註釋起來,就起到代碼混淆編譯的作用。

1
2
# Don't obfuscate. We only need dead code striping.
-dontobfuscate
可以說,這句是android工程中代碼混淆的總開關,然而,註釋了上面的代碼後,整個工程就已經是代碼混淆了嗎?不是的,這裏還要關注一個文件alps/build/core/package.mk,在這個文件中有這麼一段:

1
2
3
4
5
6
ifndef LOCAL_PROGUARD_ENABLED
ifneq ($(filter user userdebug, $(TARGET_BUILD_VARIANT)),)
    # turn on Proguard by default for user & userdebug build
    #LOCAL_PROGUARD_ENABLED :=full
endif
endif
切記:當我們需要對整個工程進行代碼混淆的時候,就把此處的 #LOCAL_PROGUARD_ENABLED :=full註釋去掉,成爲有效的宏即可。如果不想對整個工程代碼混淆,而只是相對某個模塊混淆的話,就先不要動這裏的代碼。

接着建議將真個工程new一遍,之後就可以針對具體的apk文件進行混淆文件的設置和定製了。下面以alps/packages/apps/Music爲例說說該如何對特定模塊做到混淆代碼:

在Music目錄下,我們看到一個平時不太關注,但今天一定很在意的文件名:proguard.flags ,對了,這個文件就是Music的混淆配置文件,可以打開看看(有些地方沒有這個文件,用戶可以自己手動新建一下,最好名稱也叫proguard.flags,android下默認都是這個名字)。當然,設置了配置文件還是不夠的,還需要在同目錄的Android.mk中如下設置如下兩句:

1
2
LOCAL_PROGUARD_ENABLED  := full
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
只有這樣才能讓混淆代碼有效,並且將混淆配置文件關聯起來。(有些模塊沒有這兩句句,就自己手動加上)

反之,如果用戶已經在alps/build/core/package.mk打開了全工程混淆編譯的控制點後,又在針對某個模塊時不想混淆編譯怎麼辦?這就簡單了,將模塊下的Android.mk中設置爲**LOCAL_PROGUARD_ENABLED := disabled**即可。

這樣,我們通過mm編譯後的代碼生成的apk,或者new真個工程後生成的燒機代碼,都是已經添加相應配置的混淆代碼了。

反編譯後,除過proguard.flags中定製的不需要混淆的代碼外,其他都是被混淆了,如圖所示是android中Music模塊的混淆後反編譯結果:

圖片說明文字

混淆文件的配置

在實際使用過程中,我們會發現當前apk中的有些方法和類,是要供外部使用的,而此時混淆了名稱,外部調用就會報錯了,那麼怎麼解決這個問題?此時就需要我們配置混淆的個性化文件proguard-project.txt(eclipse環境中)或者proguard.flags(android源碼環境),在其中去配置不需要混淆的類、方法和變量等。關於混淆文件的具體配置方法,大家可以去搜索下,我這裏提供一段網上有人共享的配置代碼,這個配置代碼保留了工程文件中的Activity、Application、Service、BroadcastReceiver、ContentProvider、BackupAgentHelper、Preference和ILicensingService的子類,並保留了所有的Native變量名及類名,所有類中部分以設定了固定參數格式的構造函數,枚舉等等,用來防止外部調用出錯,大家可以借鑑下,以後來配置自己的文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
-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

 -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);
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {
    public static final android.os.Parcelable$Creator *;
}
就寫這麼多了,有問題和建議,歡迎一起討論!

4.2以下版本嘗試
     1.android中默認是將代碼混淆ProGuard關閉的,在alps/build/core/proguard.flags中有下面一句,意指將默認不混淆,不需要代碼刪除,我們將這一句註釋起來,就起到代碼混淆編譯的作用。

1

2

# Don't obfuscate. We only need dead code striping.

-dontobfuscate

                  將上面改爲

1

2

# Don't obfuscate. We only need dead code striping.

#-dontobfuscate

             2.還要關注一個文件alps/build/core/package.mk,在這個文件中有這麼一段:

1

2

3

4

5

6

ifndef LOCAL_PROGUARD_ENABLED

ifneq($(filter user userdebug, $(TARGET_BUILD_VARIANT)),)

    # turn on Proguard by defaultfor user& userdebug build

    #LOCAL_PROGUARD_ENABLED :=full

endif

endif

                  不動,如果沒註釋,請註釋下,註釋爲了下面部分加擾,打開應該是全部加擾,沒有嘗試過

                  3.在自己的工程下下面Android.mk裏添加

LOCAL_PROGUARD_ENABLED  := full

LOCAL_PROGUARD_FLAG_FILES := proguard.cfg

                  proguard.cfg跟Android.mk同級目錄下。

                  4.把源碼重新全編譯下

4.4版本  可能還涉及\build\core\java.mk  具體改法在測試中
4.4的話,還需要改一處才生效

Build/core/java.mk 裏的

ifeq ($(filter obfuscation,$(LOCAL_PROGUARD_ENABLED)),)

# By default no obfuscation

# proguard_flags += -dontobfuscate ――註釋掉這句

endif  # No obfuscation
發佈了147 篇原創文章 · 獲贊 19 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章