关于Android studio混淆

来源:互联网 发布:洗车一分钱的软件 编辑:程序博客网 时间:2024/05/16 00:58

一、概述

这几天要打包APK给测试,但是一打包发现APK包有23M,经理那边自然过不了,所以就开始琢磨怎么减小APK的大小。分析原因:

1. 由于UI是按照模块给的切图,所以部分模块的切图可能存在重复,不过这种情况不多,所以对apk的大小影响不大。如果想通过减少图片来减小apk的大小,那么建议只做一套切图,单独适应xhdpi的。

2. 如果不需要做国际化,建议指定只支持中文的

                defaultConfig {  
                    resConfigs "zh"  
                }

3. 我们的app中部分用到了h5,而h5的代码是存放到assets目录下,这个目录下的文件打包的时候是不会被压缩的,所以这个目录下的文件有多大,打包之后apk就会增加多大。目前关于h5的资源代码等还不知道怎么压缩处理,各位大神有什么好的方法请教一下。

4. 这个就是重点了,android studio默认build.gradle里面配置的 minifyEnable false,这表示是不混淆,起不到防反编译的作用。


二、配置 build.gradle 文件

1. 修改配置:

buildTypes {    release {        minifyEnabled true        shrinkResources true        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'    }    debug{        minifyEnabled false        shrinkResources true        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'    }}
其中release{}指的是发布版本,也就是通过android studio工具栏中Build生成的apk;debug{}指的是调试版本,也就是通过adb连接设备直接运行生成的apk。minifyEnabled表示是否启动代码混淆,shrinkResources表示是否删除代码中无用的resource文件。

注意:想要让 shrinkResources true 生效,就必须设置 minityEnabled true。否则就算shrinkResources true,而minifyEnabled fale,那么还是不会起到作用。

proguardFiles指定的是混淆的配置文件。


三、修改混淆配置文件 proguard-rules.pro

-optimizationpasses 5          # 指定代码的压缩级别0-7-dontusemixedcaseclassnames   # 是否使用大小写混合-dontpreverify           # 混淆时是否做预校验-verbose                # 混淆时是否记录日志-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*  # 混淆时所采用的算法# 保持 AndroidManifext.xml 文件里面注册的组件不被混淆-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-keep public class * extends android.support.v4.**-keep public class * extends android.support.v7.**
#注解不被混淆
-keepattributes *Annotation*
#泛型不被混淆
 -keepattributes Signature#如果引用了v4或者v7-dontwarn android.support.**-keep class android.support.v4.**{*;}#保持 native 方法不被混淆(jni)-keepclasseswithmembernames class * { native <methods>;}#保持 Parcelable 不被混淆-keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *;}#保持 Serializable 不被混淆-keepnames class * implements java.io.Serializable
-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();}
 -keepclassmembers class * { public void *ButtonClicked(android.view.View);}#不混淆资源类-keepclassmembers class **.R$* { public static <fields>;}

# 保持枚举 enum 类不被混淆-keepclassmembers enum * {    public static **[] values();    public static ** valueOf(java.lang.String);}

 # 保持自定义控件类不被混淆-keepclasseswithmembers class * { public <init>(android.content.Context, android.util.AttributeSet);}#保持自定义控件类不被混淆-keepclassmembers class * extends android.app.Activity { public void *(android.view.View);}-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*(...);}

一般我们的项目中都会用到第三方的框架,这个也是要配置,否则会报各种异常,通常情况下,瞎子第三方jar的时候都有教怎么配置的,例如:

Gson的配置:

#-------------- Gson-------------------------keep class com.google.gson.stream.** { *; }-keepattributes EnclosingMethod #反射不混淆#这是你定义的实体类(gson解析会通过反射的方式得到bean类)-keep class 包名.**{*;}
okhttputils的配置:

#okhttp-dontwarn okhttp3.**-keep class okhttp3.**{*;}#okio-dontwarn okio.**-keep class okio.**{*;}

对于webview的混淆问题:

#解决webviewjs的交互问题(#后面的内部,JSLoadNative是js调用android的接口)-keepclassmembers class 包名.BaseActivity$JSLoadNative {    public *;}-keepattributes JavascriptInterface

四、总结

1. Android 混淆原则:
             反射用到的类不混淆
            JNI方法不混淆
            AndroidMainfest中的类不混淆,四大组件和Application的子类和Framework层下所有的类默认不会进行混淆
            Parcelable的子类和Creator静态成员变量不混淆,否则会产生android.os.BadParcelableException异常
            使用GSON、fastjson等框架时,所写的JSON对象类不混淆,否则无法将JSON解析成对应的对象
            使用第三方开源库或者引用其他第三方的SDK包时,需要在混淆文件中加入对应的混淆规则
            有用到WEBView的JS调用也需要保证写的接口方法不混淆

2. 混淆小技巧:

            对于第三方的jar包直接照着提供的修改
            对于有的类找不到,就直接-keep掉,然后再运行修改
           build.gradle文件默认不会配置debug模式,自己添加配置debug模式,这样就可以直接通过adb来调试混淆引起的一些问题了

3. 注意:

           eclipse里面是需要 -libraryjars 来导入我们使用到的jar的,但是studio里面就不需要,相反,如果你再次引用打包的时候就会报引用了两次的错误。



这样改了之后,再次打包发现apk比之前小了6M多。

0 0
原创粉丝点击