Android混淆APK直接copy使用

来源:互联网 发布:网络象棋 编辑:程序博客网 时间:2024/06/05 08:28

转载请注明出处:http://blog.csdn.net/qq_16318981/article/details/51265396
混淆APK

在Android Studio当中混淆APK实在是太简单了,借助SDK中自带的Proguard工具,只需要修改build.gradle中的一行配置即可。可以看到,现在build.gradle中minifyEnabled的值是false,这里我们只需要把值改成true,打出来的APK包就会是混淆过的了。如下所示:
release {    minifyEnabled true    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

其中minifyEnabled用于设置是否启用混淆,proguardFiles用于选定混淆配置文件。

proguard中一共有三组六个keep关键字,很多人搞不清楚它们的区别,这里我们通过一个表格来直观地看下:

关键字 描述 keep 保留类和类中的成员,防止它们被混淆或移除。 keepnames 保留类和类中的成员,防止它们被混淆,但当成员没有被引用时会被移除。 keepclassmembers 只保留类中的成员,防止它们被混淆或移除。 keepclassmembernames 只保留类中的成员,防止它们被混淆,但当成员没有被引用时会被移除。 keepclasseswithmembers 保留类和类中的成员,防止它们被混淆或移除,前提是指名的类中的成员必须存在,如果不存在则还是会混淆。

keepclasseswithmembernames 保留类和类中的成员,防止它们被混淆,但当成员没有被引用时会被移除,前提是指名的类中的成员必须存在,如果不存在则还是会混淆。
除此之外,proguard中的通配符也比较让人难懂,proguard-android.txt中就使用到了很多通配符,我们来看一下它们之间的区别:

通配符 描述 feild 匹配类中的所有字段 method 匹配类中的所有方法 init 匹配类中的所有构造函数 * 匹配任意长度字符,但不含包名分隔符(.)。

比如说我们的完整类名是com.example.test.MyActivity,使用com.,或者com.exmaple.都是无法匹配的,因为无法匹配包名中的分隔符,正确的匹配方式是com.exmaple..,或者com.exmaple.test.,这些都是可以的。但如果你不写任何其它内容,只有一个*,那就表示匹配所有的东西。
* 匹配任意长度字符,并且包含包名分隔符(.)。比如proguard-android.txt中使用的-dontwarn android.support.*就可以匹配android.support包下的所有内容,包括任意长度的子包。
* 匹配任意参数类型。比如void set*()就能匹配任意传入的参数类型,** get*()就能匹配任意返回值的类型。
… 匹配任意长度的任意类型参数。比如void test(…)就能匹配任意void test(String a)或者是void test(int a, String b)这些方法。
虽说上面表格已经解释的很详细了,但是很多人对于keep和keepclasseswithmembers这两个关键字的区别还是搞不懂。确实,它们之间用法有点太像了,我做了很多次试验它们的结果都是相同的。其实唯一的区别就在于类中声明的成员存不存在.

项目中经常使用的混淆:直接copy使用

-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#忽略警告-ignorewarnings##记录生成的日志数据,gradle build时在本项目根目录输出##    #apk 包内所有 class 的内部结构-dump class_files.txt#未混淆的类和成员-printseeds seeds.txt#列出从 apk 中删除的代码-printusage unused.txt#混淆前后的映射-printmapping mapping.txt########记录生成的日志数据,gradle build时 在本项目根目录输出-end######    #####混淆保护自己项目的部分代码以及引用的第三方jar包library#######    #-libraryjars libs/umeng-analytics-v5.2.4.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    #如果不想混淆 keep 掉-keep class com.lippi.recorder.iirfilterdesigner.** {*; }#友盟-keep class com.umeng.**{*;}#-libraryjars libs/baidumapapi_map_v3_6_1.jar 替换成自己所用版本的jar-keep class com.baidu.** { *; }-keep class vi.com.gdi.bgl.android.**{*;}-keep class com.baidu.location.**{*;}-keep class cn.easyar.engine.**{*;}-keep class vi.com.gdi.bgl.android.**{*;}-keep class com.nostra13.universalimageloader.**{*;}-keep class com.android.util.**{*;}#项目特殊处理代码    #忽略警告-dontwarn com.lippi.recorder.utils**#保留一个完整的包-keep class com.lippi.recorder.utils.** {        *;}-keep class  com.lippi.recorder.utils.AudioRecorder{*;}#如果引用了v4或者v7包-dontwarn android.support.**####混淆保护自己项目的部分代码以及引用的第三方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);}#保持自定义控件类不被混淆-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>;        !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(...);    #}    #如果用用到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.** { *; }#-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 *;#}

引入的module:比如使用到的PushSdk

-libraryjars ..\\PushSDK  #忽略警告#-dontwarn com.ta.utdid2.**-dontwarn com.umeng.**-dontwarn com.ut.device.**-dontwarn org.android.**#保持完整的包#-keep class com.ta.utdid2.**{*;}-keep class com.umeng.**{*;}-keep class com.ut.device.**{*;}-keep class org.android.**{*;}

参考: http://blog.csdn.net/guolin_blog/article/details/50451259

1 0