混淆配置

本文转自:点击打开链接

Android 混淆配置

一、proguard 原理
Java代码编译成二进制class 文件,这个class 文件也可以反编译成源代码 。除了注释外,原来的code 基本都可以看到。
为了防止重要code 被泄露,我们往往需要混淆(Obfuscation code ), 也就是把方法,字段,包和类这些java 元素的名称改成无意义的名称,这样代码结构没有变化,还可以运行,但是想弄懂代码的架构却很难。 proguard 就是这样的混淆工具,它可以分析一组class 的结构,根据用户的配置,然后把这些class 文件的可以混淆java 元素名混淆掉。在分析class 的,同时他还有其他两个功能,删除无效代码(Shrinking 收缩),和代码进行优化 (Optimization Options)。 
缺省情况下,proguard 会混淆所有代码,但是下面几种情况是不能改变java 元素的名称,否则就会这样就会导致程序出错。
 一, 我们用到反射的地方。
 二, 我们代码依赖于系统的接口,比如被系统代码调用的回调方法,这种情况最复杂。
 三, 是我们的java 元素名称是在配置文件中配置好的。
 所以使用proguard时,我们需要有个配置文件告诉proguard 哪些java 元素是不能混淆的。
二、proguard 配置
Proguard.cfg文件是用来描述混淆配置的描述文件。
自Android 2.3 SDK发布后,Google便在Android SDK Tools里加入了proguard,proguard是一个可以对.java文件进行一定程度上的代码混淆,使用proguard是一件极方便工作,在你项目中没有其他外部Jar包的情况下,在“project.properties”文件里,添加一行:
proguard.config=proguard.cfg代码即可,然后通过Android Tools(右击项目名)里导出APK即可。如果项目所使用的的SDK版本低于2.3,只需要进行%android_dir%/tools/lib目录,复制proguard.cfg文件到项目的根目录下导出APK即可。
(2.3之前版本可以拷贝proguard.cfg文件到项目工程下)


这里我们重点看看proguard.cfg文件是如何配置的?Google默认的proguard.cfg文件内容如下:
-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 com.android.vending.licensing.ILicensingService
<!--指定的类和类成员被保留->
-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 enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}
混淆中保留了继承自Activity、Service、Application、BroadcastReceiver、ContentProvider等基本组件以及com.android.vending.licensing.ILicensingService,
并保留了所有的Native变量名及类名,所有类中部分以设定了固定参数格式的构造函数,枚举等等。
最常用的配置选项:
 -dontwarn 缺省proguard 会检查每一个引用是否正确,但是第三方库里面往往有些不会用到的类,没有正确引用。如果不配置的话,系统就会报错。
 -keep 指定的类和类成员被保留作为入口 。
 -keepclassmembers 指定的类成员被保留。
 -keepclasseswithmembers 指定的类和类成员被保留,假如指定的类成员存在的话。


三、proguard 问题和风险
 代码混淆后虽然有混淆优化的好处,但是它往往也会带来如下的几点问题:
 1,混淆错误,用到第三方库的时候,必须告诉 proguard 不要检查,否则proguard 会报错。
 2,运行错误,当code 不能混淆的时候,我们必须要正确配置,否则程序会运行出错,这种情况问题最多。
 3,调试苦难,出错了,错误堆栈是混淆后的代码 ,自己也看不懂。


四、解决方案
为了防止混淆出问题,你需要熟悉你所有的code ,系统的架构 ,以及系统和你code的集成的接口,并细心分析。 同时你必须需要一轮全面的测试。 所以混淆也还是有一定风险的。 为了避免风险,你可以只是混淆部分关键的代码,但是这样你的混淆的效果也会有所降低。


常见的不能混淆的androidCode
 (1)Android 程序 ,下面这样代码混淆的时候要注意保留。
 (2)Android系统组件,系统组件有固定的方法被系统调用。
 (3) 被Android Resource 文件引用到的。名字已经固定,也不能混淆,比如自定义的View 。
 (4)Android Parcelable ,需要使用android 序列化的。
 其他Anroid 官方建议不混淆的,如
(5) android.app.backup.BackupAgentHelper
(6) android.preference.Preference
(7) com.android.vending.licensing.ILicensingService
(8) Java序列化方法,系统序列化需要固定的方法。
(9) 枚举 ,系统需要处理枚举的固定方法。
(10)native 本地方法,不能修改本地方法名
(11)annotations 注释
(12)数据库驱动
(13)有些resource 文件
(14)用到反射的地方,比如调用aidl


 如何实施?
(1)保留系统默认混淆设置。
默认系统的混淆配置会保留: Android系统组件
 自定义View
 Android Parcelable
 Android R 文件
 Android Parcelable
 枚举
 各个开发人员必须检查自己的code 是否用到反射,和其他不能混淆的地方。告诉我来修改配置文件(已经保留的就不需要了)


 目前系统不检查的第三方库为:
 -dontwarn android.support.**
 -dontwarn com.tencent.**
 -dontwarn org.dom4j.**
 -dontwarn org.slf4j.**
 -dontwarn org.http.mutipart.**
 -dontwarn org.apache.**
 -dontwarn org.apache.log4j.**
 -dontwarn org.apache.commons.logging.**
 -dontwarn org.apache.commons.codec.binary.**
 -dontwarn weibo4android.**
 
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}    设置源文件中给定的字符串常量


(2)解决export打包的报错
这个时候export提示“conversion to Dalvik format failed with error 1”错误,网上说法有好多种,最后我还是把proguard从4.4升级到4.8就解决了。官方地址是http://proguard.sourceforge.net。上面的配置文件参数可以在这里查阅。
升级办法很简单,就是把android sdk目录下的tool/proguard目录覆盖一下即可。


(3)打包出来的程序如何调试?
 一旦打包出来,就不能用eclipse的logcat去看了,这里可以用android sdk中ddms.bat的tool来看,一用就发现和logcat其实还是一个东西,就是多了个设备的选择。


(4)使用 gson 需要的配置
当Gson用到了泛型就会有报错,这个真给郁闷了半天,提示“Missing type parameter”。最后找到一个资料给了一个解决办法,
参考:http://stackoverflow.com/questions/8129040/proguard-missing-type-parameter
另外我又用到了JsonObject,提交的Object里面的members居然被改成了a。所以上面给的东西还不够,还要加上
 # 用到自己拼接的JsonObject
 -keep class com.google.gson.JsonObject { *; }


个人建议减少这些依赖包混淆带来的麻烦,干脆都全部保留不混淆。例如
 -keep class com.badlogic.** { *; }
 -keep class * implements com.badlogic.gdx.utils.Json*
 -keep class com.google.** { *; }


(5)使用libgdx需要的配置
 参考http://code.google.com/p/libgdx-users/wiki/Ant


(6)引入第三方Jar包时配置
在其中加入以下代码:-libraryjars %lib_jar_path%
有几个Jar包,便添加几次,如在项目的libs目录下有a.jar,b.jar,c.jar三个Jar包:
-libraryjars libs/a.jar
-libraryjars libs/b.jar
-libraryjars libs/c.jar
此外,还有些特殊情况,会令导出发生异常,视具体异常情况而定,修改proguard.cfg文件。
比如出现了以下异常:
Warning: com.google.android.maps.MapView: can't find referenced class com.android.mkstubs.stubber.MethodStubber
Warning: com.google.android.maps.MapView$1: can't find referenced class com.android.mkstubs.stubber.MethodStubber
即:
Warning: %class_full_name%: can't find referenced class %class_full_name%
这种异常情况,需要在proguard.cfg文件中,添加以下代码:
-dontwarn %class_full_name% 不检查指定包的文件
即可,便以上面例子而言,应当如下:
-dontwarn com.google.android.maps.*
等等,此类情况修改proguard.cfg文件即可,还有种特殊情况,需要对引入的Jar包进行修改,如下:
Warning: library class android.content.res.XmlResourceParser extends or implements program class org.xmlpull.v1.XmlPullParser
Warning: library class android.view.LayoutInflater depends on program class org.xmlpull.v1.XmlPullParser
     这是因为引用的Jar包中含有xmlpull类库,Android系统的类库中已经包含了xmlpull,这样混淆出现了冲突,解决办法是把它里面已存在的和系统库冲突的类去掉,就可以了,产生冲突的类可见控制台输出。
    另外对不想混淆的类/方法/变量,可以使用-keep指定,具体参考proguard.cfg文件写法。
(7)验证打包效果
 利用了apktool的反编译工具,把打包文件又解压了看了一下,如果包路径、类名、变量名、方法名这些变化和你期望一致,那就OK了。命令:
apktool.bat d xxx.apk destdir


五、配置实例
 -injars  androidtest.jar【jar包所在地址】 
 -outjars  out【输出地址】
 -libraryjars    'D:\android-sdk-windows\platforms\android-9\android.jar' 【引用的库的jar,用于解析injars所指定的jar类】
 -optimizationpasses 5
 -dontusemixedcaseclassnames 【混淆时不会产生形形色色的类名 】
 -dontskipnonpubliclibraryclasses 【指定不去忽略非公共的库类。 】
 -dontpreverify 【不预校验】
 -verbose
-dump class_files.txt 
-printseeds seeds.txt 
-printusage unused.txt 
-printmapping mapping.txt 
 -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* 【优化】
-allowaccessmodification
-keepattributes *Annotation* //保持Annotion属性
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
-repackageclasses ''
 -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
 -keep public abstract interface com.asqw.android.Listener{
 public protected <methods>;  【所有方法不进行混淆】
 }
 -keep public class com.asqw.android{
 public void Start(java.lang.String); 【对该方法不进行混淆】
 }
 -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 *;
 }
# Explicitly preserve all serialization members. The Serializable interface
# is only a marker interface, so it wouldn't save them.
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}
##---------------Begin: proguard configuration for Gson  ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }


# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
##---------------End: proguard configuration for Gson  ----------
 //不混淆指定包下的类 
 -keep class com.aspire.**
参考:http://www.eoeandroid.com/thread-209210-1-1.html




六、常见问题
1、打包过程中,提示 Warning: can't find superclass or interface/ Warning: can't find referenced class等警告信息!
解决方法:
(1)在配置文件中使用-libraryjars选项来指定代码里引用到的所有库,包括Java运行库。
(2)确保报错的类没有在你的项目中使用到,使用"-dontwarn 类名正则表达式"屏蔽警告。
(3)使用keep保持第三方内容(jar包)不混淆。
以引入android-support-v4.jar包为例,那么在工程打包混淆时,就会出现报错提示。例如提示你:You may need to specify additional library jars (using '-libraryjars')。
修改progurad.cfg文件,添加如下配置:
在proguard.cfg里的后面,添加如下内容:
 [java]
 -libraryjars /android-support-v4.jar //指定引入的外部jar包
 -dontwarn android.support.v4.**  //声明指定包不做引用检查,用来屏蔽警告
 -keep class android.support.v4.** { *; } //声明不混淆的类
 -keep public class * extends android.support.v4.** 
 -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.** { *;}
最后打包成功,还要在机子上跑跑,看看有没有问题。




注意的是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 <methods>;  
}  
-keepclasseswithmembers class * {   // 对于所有类,有这个构造函数不进行混淆,主要是为了在layout中的,自定义的view
    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 {  // 这个主要是在layout 中写的onclick方法android:οnclick="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 *;  
}


参考:http://fonter.iteye.com/blog/489728
2、程序中用到了gson的new typeToken,结果打包成apk发布时,发现抛出异常。
解决:第一种:在 proguard.cfg中添加,
-dontobfuscate 
-dontoptimize
第二种:在 proguard.cfg中添加,
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature


# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }


# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
这两种方法都测试可行,第一个方法没有混淆编译,第二个方法能够混淆编译。
参考:http://stackoverflow.com/questions/8129040/proguard-missing-type-parameter
3、程序中使用泛型、反射等类时导致运行错误!
解决:由于前面开发数据操作类,所以利用反射,封装了一个BaseDao,本来在平常的时候,调试都没有出问题,可是直到用了Proguard混淆以后,就出现各种错误。下面就把我遇见的问题分享出来吧。
 第一个,类型转换错误。
因为我用的泛型,所以在调用某些方法的时候,会出现这种错误,后面在混淆配置文件加了一个过滤泛型的语句,如下。
  -keepattributes Signature
 过后,就没有出现类似的类型转换错误。
 第二个,空指针异常。
原来我 model的 set/get方法名全部都被混淆了,导致找不到实体类无法get或者set,返回的也就是null值,自然下面用到这个方法的返回值就会抛出空指针异常。这个时候应该做的事情是阻止proguard对实体类的混淆,比如:
-keep public class mypackage.MyBean { 
public void setMyProperty(int); 
public int getMyProperty();
}  
或者干脆把model包下面的所有类,全部过滤掉。
-keep public class mypacke.MyBean


总结:如要用到反射,反射一般就会利用到泛型,所以必须要把泛型的全部过滤掉,如果有根据变量名或者方法名判断的,记得所在的类需过滤掉,之中还有用到 annotation的地方,要加入一行代码,如下:
-keepattributes *Annotation*
这样就能过滤掉所有的annotation,否则也会抛出空指针异常。
附录 proguard.cfg文件
##---------------Begin: proguard configuration common for all Android apps ----------
<!-- Specify the input jars, output jars, and library jars. -->
##指定输入/输出jar以及第三方库
-injars  in.jar
-outjars out.jar


-libraryjars ${java.home}/lib/rt.jar
<!-- -libraryjars junit.jar    -->
<!-- -libraryjars servlet.jar  -->
<!-- -libraryjars jai_core.jar -->
<!-- ...                       -->
-optimizationpasses 5
##混淆时不会产生形形色色的类名
-dontusemixedcaseclassnames
##指定不去忽略非公共的库类。
-dontskipnonpubliclibraryclasses
##指定不去忽略包可见的库类的成员
-dontskipnonpubliclibraryclassmembers
##不预校验
-dontpreverify


-verbose
-dump class_files.txt 
-printseeds seeds.txt 
-printusage unused.txt 
-printmapping mapping.txt 
##优化
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*


-allowaccessmodification
##保持annotation注释属性,泛型中常用
-keepattributes *Annotation*
-renamesourcefileattribute SourceFile
##保持SourceFile/LineNumberTable属性
-keepattributes SourceFile,LineNumberTable
-repackageclasses ''


##继承之下面的类不进行混淆保持原样
-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
-dontnote com.android.vending.licensing.ILicensingService


# 序列化Explicitly preserve all serialization members. The Serializable interface
# is only a marker interface, so it wouldn't save them.
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}


#Native方法 Preserve all native method names and the names of their classes.
-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);
}


# 内部类 Preserve static fields of inner classes of R classes that might be accessed
# through introspection.
-keepclassmembers class **.R$* {
  public static <fields>;
}


# 举Preserve the special static methods that are required in all enumeration classes.
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}


-keep public class * {
    public protected *;
}
##Parcelable子类
-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}


##---------------End: proguard configuration common for all Android apps ----------




##---------------GSON配置 Begin: proguard configuration for Gson  ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature


# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }


# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }


##---------------End: proguard configuration for Gson  ----------


##-------------------自定义配置----------------------###
##保留指定包下面的内容不混淆
-keep public class 包名.**{ *; }
##保留指定类不混淆
-keep public class 包名.类名{ *;}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值