Android中的代码混淆

释放双眼,带上耳机,听听看~!

混淆规则

因为Android是使用Java开发的,所以开发者可以使用ProGuard对代码进行混淆。SDK已经集成了ProGuard工具,开发者可以从SDK目录下的toolsproguard目录中进行查看。

    ProGuard是一个免费的**Java****类文件收缩,优化,混淆和预校验器。它可以检测并删除未使用的类,字段,方法和属性。它可以优化字节码,并删除未使用的指令。它可以将类、字段和方法使用短无意义的名称进行重命名**。最后,预校验的Java6或针对Java MicroEdition的所述处理后的码。

下面就和大家分享一下对使用了第三方库的项目进行混淆的经验。

ProGuard默认会对第三方库也进行混淆的,而第三方库有的已经混淆过了,有的使用了Java反射技术,所以我们在进行代码混淆的时候要排除这些第三方库。排除对第三方库的混淆需要在混淆规则文件(通常是:proguard-project.txt或proguard.cfg或proguard-rules.pro或proguard-rules.txt也可以是其它的文件名只要在配置文件中将含有混淆规则的文件名配置进去就行了)中添加如下规则:

1.如果使用了Gson之类的工具要使JavaBean类即实体类不被混淆。

2.如果使用了自定义控件那么要保证它们不参与混淆。

3.如果使用了枚举要保证枚举不被混淆。

4.对第三方库中的类不进行混淆

a.混淆时保护引用的第三方jar包

如:-libraryjars libs/baidumapapi_v3_2_0.jar #保护引用的第三方jar包不被混淆

注意:在使用Eclipse+ADT时需要加入-libraryjars libs/…,如果你是使用Android Studio开发的项目则不需要加入libs包中的jar包,这是因为,通过Android Studio进行混淆代码时,默认已经将 lib目录中的 jar 都已经添加到打包脚本中,所以不需要再次手动添加,否则会出现“ java.io.IOException: The same input jar is specified twice” 错误。

b.混淆时保护第三方jar包中的类不被混淆

如:-keep class com.baidu.** { ; } #让ProGuard不要警告找不到com.baidu.*这个包里面的类的相关引用

-dontwarn com.baidu.** #保持com.baidu.**这个包里面的所有类和所有方法不被混淆。

附:小编开发中用到的一些混淆规则,大家可以根据需要复制到自己的项目中的混淆规则的文件中即可。

[plain] view plain copy [图片上传失败…(image-96b93b-1530078982655)] [图片上传失败…(image-e32e22-1530078982651)]

  1. ################common###############
  2. -keep class com.jph.android.entity.** { *; } #实体类不参与混淆
  3. -keep class com.jph.android.view.** { *; } #自定义控件不参与混淆
  4. ################baidu map###############
  5. -libraryjars libs/baidumapapi_v3_2_0.jar
  6. -libraryjars libs/locSDK_5.0.jar
  7. -keep class com.baidu.** { *; }
  8. -keep class vi.com.gdi.bgl.android.*{;}
  9. -dontwarn com.baidu.**
  10. ################afinal##################
  11. -libraryjars libs/afinal_0.5_bin.jar

  12. -keep class net.tsz.afinal.** { *; }

  13. -keep public class * extends net.tsz.afinal.**

  14. -keep public interface net.tsz.afinal.** {*;}

  15. -dontwarn net.tsz.afinal.**

  16. ################xutils##################
  17. -libraryjars libs/xUtils-2.6.14.jar
  18. -keep class com.lidroid.xutils.** { *; }
  19. -keep public class * extends com.lidroid.xutils.**
  20. -keepattributes Signature
  21. -keepattributes Annotation
  22. -keep public interface com.lidroid.xutils.** {*;}
  23. -dontwarn com.lidroid.xutils.**
  24. -keepclasseswithmembers class com.jph.android.entity.** {
  25. <fields>;
  26. <methods>;
  27. }
  28. ################支付宝##################
  29. -libraryjars libs/alipaysecsdk.jar
  30. -libraryjars libs/alipayutdid.jar
  31. -libraryjars libs/alipaysdk.jar
  32. -keep class com.alipay.android.app.IAliPay{*;}
  33. -keep class com.alipay.android.app.IAlixPay{*;}
  34. -keep class com.alipay.android.app.IRemoteServiceCallback{*;}
  35. -keep class com.alipay.android.app.lib.ResourceMap{*;}
  36. ################gson##################
  37. -libraryjars libs/gson-2.2.4.jar
  38. -keep class com.google.gson.** {*;}
  39. -keep class com.google.*{;}

  40. -keep class sun.misc.Unsafe { *; }
  41. -keep class com.google.gson.stream.** { *; }
  42. -keep class com.google.gson.examples.android.model.** { *; }
  43. -keep class com.google.** {
  44. <fields>;
  45. <methods>;
  46. }
  47. -keepclassmembers class * implements java.io.Serializable {
  48. static final long serialVersionUID;
  49. private static final java.io.ObjectStreamField[] serialPersistentFields;
  50. private void writeObject(java.io.ObjectOutputStream);
  51. private void readObject(java.io.ObjectInputStream);
  52. java.lang.Object writeReplace();
  53. java.lang.Object readResolve();
  54. }
  55. -dontwarn com.google.gson.**
  56. ################httpmime/httpcore##########
  57. -libraryjars libs/httpcore-4.3.2.jar
  58. -libraryjars libs/httpmime-4.3.5.jar
  59. -keep class org.apache.http.** {*;}
  60. -dontwarn org.apache.http.**
  61. ####################jpush##################
  62. -libraryjars libs/jpush-sdk-release1.7.1.jar
  63. -keep class cn.jpush.** { *; }
  64. -keep public class com.umeng.fb.ui.ThreadView { } #双向反馈功能代码不混淆
  65. -dontwarn cn.jpush.**
  66. -keepclassmembers class * {
  67. public <init>(org.json.JSONObject);
  68. }
  69. 不混淆R类

  70. -keep public class com.jph.android.R$*{
  71. public static final int *;
  72. }
  73. -keepclassmembers enum * {
  74. public static **[] values();
  75. public static ** valueOf(java.lang.String);
  76. }
  77. ####################umeng##################
  78. -libraryjars libs/umeng-analytics-v5.2.4.jar
  79. -keep class com.umeng.analytics.** {*;}
  80. -dontwarn com.umeng.analytics.**
  81. -keep public class * extends com.umeng.**

  82. -keep public class * extends com.umeng.analytics.**

  83. -keep public class * extends com.umeng.common.**

  84. -keep public class * extends com.umeng.newxp.**

  85. -keep class com.umeng.** { *; }
  86. -keep class com.umeng.analytics.** { *; }
  87. -keep class com.umeng.common.** { *; }
  88. -keep class com.umeng.newxp.** { *; }
  89. -keepclassmembers class * {
  90. public <init>(org.json.JSONObject);
  91. }
  92. -keep class com.umeng.**
  93. -keep public class com.idea.fifaalarmclock.app.R$*{
  94. public static final int *;
  95. }
  96. -keep public class com.umeng.fb.ui.ThreadView {
  97. }
  98. -dontwarn com.umeng.**
  99. -dontwarn org.apache.commons.**
  100. -keep public class * extends com.umeng.**
  101. -keep class com.umeng.** {*; }
  102. ####################universal-image-loader########
  103. -libraryjars libs/universal-image-loader-1.9.3.jar
  104. -keep class com.nostra13.universalimageloader.** {*;}
  105. -dontwarn com.nostra13.universalimageloader.**
  106. ####################zxing#####################
  107. -libraryjars libs/zxing.jar
  108. -libraryjars libs/zxing_apply.jar
  109. -keep class com.google.zxing.** {*;}
  110. -dontwarn com.google.zxing.**
  111. ####################BASE64Decoder##################
  112. -libraryjars libs/sun.misc.BASE64Decoder.jar
  113. ####################support.v4#####################
  114. -libraryjars libs/android-support-v4.jar
  115. -keep class android.support.v4.** { *; }
  116. -dontwarn android.support.v4.**
  117. ###################other####################
  118. slidingmenu 的混淆

  119. -dontwarn com.jeremyfeinstein.slidingmenu.lib.**
  120. -keep class com.jeremyfeinstein.slidingmenu.lib.** { *; }
  121. ActionBarSherlock混淆

  122. -dontwarn com.actionbarsherlock.**
  123. -keep class com.actionbarsherlock.** { *; }
  124. -keep interface com.actionbarsherlock.** { *; }
  125. -keep class * extends java.lang.annotation.Annotation { *; }
  126. -keepclasseswithmembernames class * {
  127. native <methods>;
  128. }
  129. -keep class com.jph.android.entity.** {
  130. <fields>;
  131. <methods>;
  132. }
  133. -dontwarn android.support.**
  134. -dontwarn com.slidingmenu.lib.app.SlidingMapActivity
  135. -keep class android.support.** { *; }
  136. -keep class com.actionbarsherlock.** { *; }
  137. -keep interface com.actionbarsherlock.** { *; }
  138. -keep class com.slidingmenu.** { *; }
  139. -keep interface com.slidingmenu.** { *; }

推荐阅读:《Android****开发之反编译与防止反编译

Android****代码混淆指南

proguard.cfg配置文件

?

|

 

|

#``指定代码的压缩级别

-optimizationpasses 5

#``包明不混合大小写

-dontusemixedcaseclassnames

#``不去忽略非公共的库类

-dontskipnonpubliclibraryclasses

#``优化 不优化输入的类文件

-dontoptimize

#``预校验

-dontpreverify

#``混淆时是否记录日志

-verbose

# 混淆时所采用的算法

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

#``保护注解

-keepattributes *Annotation*

# 保持哪些类不被混淆

-keep **public class**``* **extends **``android.app.Fragment

-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

#``如果有引用v4包可以添加下面这行

-keep **public class**``* **extends **``android.support.v4.app.Fragment

#``忽略警告

-ignorewarning

#####################``记录生成的日志数据,gradle build时在本项目根目录输出################

#apk 包内所有 **class**``的内部结构

-dumpclass_files.txt

#``未混淆的类和成员

-printseeds seeds.txt

#``列出从 apk 中删除的代码

-printusage unused.txt

#``混淆前后的映射

-printmapping mapping.txt

#####################``记录生成的日志数据,gradle build时 在本项目根目录输出-end################

################<span></span>``混淆保护自己项目的部分代码以及引用的第三方jar包library#########################

#-libraryjars libs/umeng-analytics-v5.2.4.jar

#-libraryjars libs/alipaysd<span></span>k.jar

#<span></span>-libraryjars libs/alipaysecsdk.jar

#-libraryjars libs/alipayutdid.jar

#-libraryjars libs/wup-1.0.0-SNAPSHOT.jar

#-libraryjars libs/weibosdkcore.jar

#``三星应用市场需要添加:sdk-v1.0.0.jar,look-v1.0.1.jar

#-libraryjars libs/sdk-v1.0.0.jar

#-libraryjars libs/look-v1.0.1.jar

#``我是以libaray的形式引用了一个图片加载框架,如果不想混淆 keep 掉

-keep **class**``com.nostra13.universalimageloader.** { *; }

#``友盟

-keep **class**``com.umeng.**{*;}

#``支付宝

-keep **class**``com.alipay.android.app.IAliPay{*;}

-keep **class**``com.alipay.android.app.IAlixPay{*;}

-keep **class**``com.alipay.android.app.IRemoteServiceCallback{*;}

-keep **class**``com.alipay.android.app.lib.ResourceMap{*;}

#``信鸽推送

-keep **class**``com.tencent.android.tpush.** {* ;}

-keep **class**``com.tencent.mid.** {* ;}

#``自己项目特殊处理代码

#``忽略警告

-dontwarn com.veidy.mobile.common.**

#``保留一个完整的包

-keep **class**``com.veidy.mobile.common.** {

*;

}

-keep **class** com.veidy.activity.login.WebLoginActivity{*;}

-keep **class** com.veidy.activity.UserInfoFragment{*;}

-keep **class** com.veidy.activity.HomeFragmentActivity{*;}

-keep **class** com.veidy.activity.CityActivity{*;}

-keep **class** com.veidy.activity.ClinikActivity{*;}

#``如果引用了v4或者v7包

-dontwarn android.support.**

############<span></span>``混淆保护自己项目的部分代码以及引用的第三方jar包library-end##################

-keep **publicclass**``* **extends**``android.view.View {

**public**``<init>(android.content.Context);

**public**``<init>(android.content.Context, android.util.AttributeSet);

**public**``<init>(android.content.Context, android.util.AttributeSet, int);

**public**``voidset*(...);

}

#``保持 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);

}

#``保持 Parcelable 不被混淆

-keep **class**``* **implements**``android.os.Parcelable {

**publicstatic**``final android.os.Parcelable$Creator *;

}

#``保持 Serializable 不被混淆

-keepnames **class**``* **implements**``java.io.Serializable

#``保持 Serializable 不被混淆并且enum 类也不被混淆

-keepclassmembers **class**``* **implements**``java.io.Serializable {

**static**``final longserialVersionUID;

**privatestatic**``final java.io.ObjectStreamField[] serialPersistentFields;

!**static**!transient <fields>;

!**private**<fields><span></span>;

!**private**<methods>;

**private**``voidwriteObject(java.io.ObjectOutputStream);

**private**``voidreadObject(java.io.ObjectInputStream);

java.lang.Object writeReplace();

java.lang.Object readResolve();

}

#``保持枚举 enum 类不被混淆 如果混淆报错,建议直接使用上面的 -keepclassmembers**class*** **implements**``java.io.Serializable``即可

#-keepclassmembers enum * {

# **publicstatic**``**[] values();

# **publicstatic**``** valueOf(java.lang.String);

#}

-keepclassmembers **class**``* {

**public**``void*ButtonClicked(android.view.View);

}

#``不混淆资源类

-keepclassmembers **class**``**.R$* {

**publicstatic**``<fields>;

}

#``避免混淆泛型 如果混淆报错建议关掉

#–keepattributes Signature

#``移除log 测试了下没有用还是建议自己定义一个开关控制是否输出日志

#-assumenosideeffects **class**``android.util.Log {

# **publicstatic**``booleanisLoggable(java.lang.String, int);

# **publicstatic**``intv(...);

# **publicstatic**``inti(...);

# **publicstatic**``intw(...);

# **publicstatic**``intd(...);

# **publicstatic**``inte(...);

#}

|

另外加上一段,如果用用到Gson解析包的,直接添加下面这几行就能成功混淆,不然会报错。

?

|

 

|

#gson

#-libraryjars libs/gson-2.2.2.jar

-keepattributes Signature

# Gson specific classes

-keep class sun.misc.Unsafe { *; }

# Application classes that will be serialized/deserialized over Gson

-keep class com.google.gson.examples.android.model.** { *; }

|

如果你使用了webview

?

|

 

|

# webview + js

-keepattributes *JavascriptInterface*

# keep 使用 webview 的类

-keepclassmembers **class** com.veidy.activity.WebViewActivity {

**public**``*;

}

# keep 使用 webview 的类的所有的内部类

-keepclassmembers **class** com.veidy.activity.WebViewActivity$*{

*;

}

|

混淆后生成apk文件比混淆前生成的apk文件要小不少

人已赞赏
Android文章

Android开发之RTMPDump的使用

2020-1-3 17:14:58

Android文章

Android屏幕适配(非常好用)

2020-1-3 18:29:49

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
有新消息 消息中心
搜索