Android Studio 代码混淆

在Android studio 进行代码混淆配置。java

proguard 配置android

-keepclasseswithmembers 指定的类和类成员被保留,假如指定的类成员存在的话。算法

-dontwarn 缺省proguard 会检查每个引用是否正确,可是第三方库里面每每有些不会用到的类,没有正确引用。若是不配置的话,系统就会报错。数据库

-keep 指定的类和类成员被保留做为 入口 。app

-keepclassmembers 指定的类成员被保留。框架


proguard 问题和风险ide

代码混淆后虽然有混淆优化的好处,可是它每每也会带来以下的几点问题测试

混淆错误,用到第三方库的时候,必须告诉 proguard 不要检查,不然proguard 会报错。gradle

运行错误,当code 不能混淆的时候,咱们必需要正确配置,不然程序会运行出错,这种状况问题最多。优化

调试苦难,出错了,错误堆栈是混淆后的代码 ,本身也看不懂。


不能混淆的代码

下面这样代码混淆的时候要注意保留。

Android系统组件,系统组件有固定的方法被系统调用。

被Android Resource 文件引用到的。名字已经固定,也不能混淆,好比自定义的View 

Android Parcelable ,须要使用android 序列化的。

Java序列化方法,系统序列化须要固定的方法。

枚举 ,系统须要处理枚举的固定方法

本地方法,不能修改本地方法名

annotations 注释

数据库驱动

有些resource 文件

用到反射的地方

其余Anroid 官方建议 不混淆的,如

android.app.backup.BackupAgentHelper

android.preference.Preference

com.android.vending.licensing.ILicensingService


混淆配置

proguard 参数

-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}    设置源文件中给定的字符串常量



下面是一个混淆模板吧。注释很清楚。

#指定代码的压缩级别
-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 的内部结构
-dump class_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 public class * 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 void set*(...);
}
#保持 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 {
  public static final android.os.Parcelable$Creator *;
}
#保持 Serializable 不被混淆
-keepnames class * implements java.io.Serializable
#保持 Serializable 不被混淆而且enum 类也不被混淆
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    !static !transient <fields>;
    !private <fields><span></span>;
    !private <methods>;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}
#保持枚举 enum 类不被混淆 若是混淆报错,建议直接使用上面的 -keepclassmembers class * implements java.io.Serializable便可
#-keepclassmembers enum * {
#  public static **[] values();
#  public static ** valueOf(java.lang.String);
#}
-keepclassmembers class * {
    public void *ButtonClicked(android.view.View);
}
#不混淆资源类
-keepclassmembers class **.R$* {
    public static <fields>;
}
#避免混淆泛型 若是混淆报错建议关掉
#–keepattributes Signature
#移除log 测试了下没有用仍是建议本身定义一个开关控制是否输出日志
#-assumenosideeffects class android.util.Log {
#    public static boolean isLoggable(java.lang.String, int);
#    public static int v(...);
#    public static int i(...);
#    public static int w(...);
#    public static int d(...);
#    public static int e(...);
#}
相关文章
相关标签/搜索