Android 混淆出錯各種解決辦法


android使用打包過程中proguard混淆后, 會導致一些錯誤
1. 寫在視圖xml中的onClick響應出錯. 因為寫在xml中的onClick是通過反射調用的, proguard認為它們沒有在代碼中被調用過, 所以將它們從代碼中除掉或改名了. 解決方法:
在proguard.cfg中添加以下代碼, 就可以防止被配在視圖xml中的onClick方法被proguard優化掉
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}

2. jni反調java方法
這些類或方法同樣可能會被proguard認為沒有調用過而被除掉, 或都被改名. 這些方法最好統一寫在一個類中, 然后這個類不作優化, 或是找出所有jni調用過的類與方法, 在proguard.cfg中配置, 不對它們作優化

3. 其它反射調用的java類與方法
使用反射時一定要注意proguard可能會認為那些方法未被調用過, 會在代碼優化過程中將它們改名或除去. 在使用反射的地方一定要在proguard.cfg中配置, 不優化反射調用過的類和方法

最后在proguard優化過后會產生一些文件
dump.txt – 描述.apk文件中所有類文件間的內部結構
mapping.txt – 列出了原始的類,方法和字段名與混淆后代碼間的映射。這個文件很重要,當你從release版本中收到一個bug報告時,可以用它來翻譯被混淆的代碼。
seeds.txt – 列出了未被混淆的類和成員
usage.txt – 列出了從.apk中刪除的代碼

要注意分析mapping.txt與usage.txt看xml視圖中寫的onClick響應函數, jni調用到的java類與方法, 反射調用過的類與方法是否被混淆或重命名

 

 

-keep class com.badlogic.gdx.backends.android.**{ *;}
像這樣的只是不混淆:這個包下的類(不包括子包里的東西),用到一個第三文的類就要把這個類所在的包,像上面加上

還要注意的是android-support-v4.jar這個包問題,這里加上了對這個jar包的處理

第三方jar的混淆,

-optimizationpasses 5
-dontusemixedcaseclassnames 
-dontskipnonpubliclibraryclasses 
-dontpreverify 
-verbose 
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* 

-keep public class * extends android.app.Activity                          // 繼承activity,application,service,broadcastReceiver,contentprovider....不進行混淆
-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

                                                                                                                      // 這里處理第三方的jar包,第三方JAR包處理開始
-libraryjars /libs/android-support-v4.jar
-libraryjars /libs/gdx-backend-android.jar
-libraryjars /libs/gdx.jar

                                                                                                                        // 這里不對第三方的jar包的提出WARN    
-dontwarn com.badlogic.**
-dontwarn android.support.v4.**
-dontwarn android.support.v4.view.**

                                                                                                                        // 這里對第三方jar包的類不進行混淆
-keep class com.badlogic.gdx.backends.android.**{ *;}
-keep class com.badlogic.gdx.**{ *;}
-keep class com.badlogic.gdx.graphics.g2d.**{ *;}
-keep class com.badlogic.gdx.graphics.**{ *;}
-keep class android.support.v4.view.**{ *;}

                                                                                                                            // 這里第三方JAR包處理結束

-keepclasseswithmembernames class * {                                                           // natvie 方法不混淆
    native ; 

-keepclasseswithmembers class * {                                                                    // 對於所有類,有這個構造函數不進行混淆,主要是為了在layout中的,自定義的view
    public (android.content.Context, android.util.AttributeSet); 

-keepclasseswithmembers class * { 
    public (android.content.Context, android.util.AttributeSet, int); 

-keepclassmembers class * extends android.app.Activity {                                   // 這個主要是在layout 中寫的onclick方法android:onclick="onClick",不進行混淆
   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 *; 
}

 

 

1-----------------------------------------------引用--------------------------------------------------------

如果工程引入了Android-support-v4的jar類庫,那么在工程打包混淆時,就會出現報錯提示。例如提示你:You may need to specify additional library jars (using '-libraryjars')。
 
這里先給出解決方案,稍后我們再來解釋如何處理類似情況:
 
在proguard.cfg里的后面,添加如下內容:
 1.-libraryjars /android-support-v4.jar 
 2.-dontwarn android.support.v4.** 
 3.-keep class android.support.v4.** { *; } 
 4.-keep public class * extends android.support.v4.** 
 5.-keep public class * extends android.app.Fragment 
 
然后你再打包看看,應該可以正常生成apk安裝包了。
 
打包出錯:
情況一:
 "類1 can't find referenced class 類2" 字面上的意思就是類1找不到類2的引用;它會建議你:"You may need to specify additional library jars (using '-libraryjars').";
需要使用-libraryjars加上項目中使用到的第三方庫就OK了。
例如:-libraryjars /android-support-v4.jar
注意:這里引用方式是當前工程的根目錄(也可以配置其他目錄),也就是說,你要把第三方jar放到當前目錄下,否則就會警告說找不到jar文件!
 
情況二:
例如: can't find superclass or interface android.os.Parcelable$ClassLoaderCreator,碰到這樣的情況,可以使用-dontwarn com.xx.yy.**,不對錯誤提出警告。
注意:使用這個方式的話,要確保自己沒有用到這個庫里面的類!否則就會拋ClassNotFoundException!
 
情況三:
在工程中確實用到了該類,采用上面方式還是不行。這個時候就要再增加一項:-keep class com.xx.yy.** { *;},讓當前類不混淆。
 
小結:
對於引用第三方包的情況,可以采用下面方式避免打包出錯:
-libraryjars /aaa.jar
-dontwarn com.xx.yy.**
-keep class com.xx.yy.** { *;}
 
最后打包成功,還要在機子上跑跑,看看有沒有問題。

本篇文章來源於 Linux公社網站(www.linuxidc.com)  原文鏈接:http://www.linuxidc.com/Linux/2012-07/66798.htm

-----------------------------------------------------------------------------------2--------------------------------------------------------------------

proguard.cfg配置
 
稍微深入想一下混淆后的結果,你就會發現,如果一些提供給外部的類、方法、變量等名字被改變了,那么程序本身的功能就無法正常實現。那么Proguard如何知道哪些東西是可以改名,而哪些是不能改變的呢?
 
這個是靠proguard.cfg文件來進行配置的。Android工程中默認自動生成的proguard.cfg已經針對Android的一般情況進行了配置,我們打開這個配置文件。內容大概如下:
 1.-optimizationpasses 5 
2.-dontusemixedcaseclassnames 
3.-dontskipnonpubliclibraryclasses 
4.-dontpreverify 
5.-verbose 
6.-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* 
7. 
8.-keep public class * extends android.app.Activity 
9.-keep public class * extends android.app.Application 
10.-keep public class * extends android.app.Service 
11.-keep public class * extends android.content.BroadcastReceiver 
12.-keep public class * extends android.content.ContentProvider 
13.-keep public class * extends android.app.backup.BackupAgentHelper 
14.-keep public class * extends android.preference.Preference 
15.-keep public class com.android.vending.licensing.ILicensingService 
16. 
17.-keepclasseswithmembernames class * { 
18.    native ; 
19.} 
20. 
21.-keepclasseswithmembers class * { 
22.    public (android.content.Context, android.util.AttributeSet); 
23.} 
24. 
25.-keepclasseswithmembers class * { 
26.    public (android.content.Context, android.util.AttributeSet, int); 
27.} 
28. 
29.-keepclassmembers class * extends android.app.Activity { 
30.   public void *(android.view.View); 
31.} 
32. 
33.-keepclassmembers enum * { 
34.    public static **[] values(); 
35.    public static ** valueOf(java.lang.String); 
36.} 
37. 
38.-keep class * implements android.os.Parcelable { 
39.  public static final android.os.Parcelable$Creator *; 
40.} 
 
它主要保留了繼承自Activity、Application、Service、BroadcastReceiver、ContentProvider、 BackupAgentHelper、Preference和ILicensingService的子類。因為這些子類,都是可能被外部調用的。
 
另外,它還保留了含有native方法的類、構造函數從xml構造的類(一般為View的子類)、枚舉類型中的values和valueOf靜態方法、繼承Parcelable的跨進程數據類。
 
在實際的一個工程項目中,可能Google自動生成的配置不能勝任我們的混淆工作。所以,我們往往需要自己編寫一些ProGuard配置。這方面的資料在官網的Manual -> Usage里有詳細說明,大家可以研究一下。

打包
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM