一.有关混淆:
什么是代码混淆
Java是一种跨平台的、解释型语言,Java源代码编译成中间“字节码”存储于class文件中。由于跨平台的需要,Java字节码中包含了很多源代码信息,如变量名、方法名,并且通过这些名称来访问变量和方法,这些符号带有许多语义信息,很容易被反编译成Java源代码。为了防止这种现象,我们可以使用Java混淆器对Java字节码进行混淆。
混淆就是对发布出去的程序进行重新组织和处理,使得处理后的代码与处理前代码完成相同的功能,而混淆后的代码很难被反编译,即使反编译成功也很难得出程序的真正语义。被混淆过的程序代码,仍然遵照原来的档案格式和指令集,执行结果也与混淆前一样,只是混淆器将代码中的所有变量、函数、类的名称变为简短的英文字母代号,在缺乏相应的函数名和程序注释的情况下,即使被反编译,也将难以阅读。同时混淆是不可逆的,在混淆的过程中一些不影响正常运行的信息将永久丢失,这些信息的丢失使程序变得更加难以理解。
混淆器的作用不仅仅是保护代码,它也有精简编译后程序大小的作用。由于以上介绍的缩短变量和函数名以及丢失部分信息的原因,编译后jar文件体积大约能减少25%,这对当前费用较贵的无线网络传输是有一定意义的。
二.在Android Studio中混淆做以下总结:
首先,需要在app/proguard-rules.pro文件中,添加混淆文件;
然后,在build.gradle中去开启混淆:
- buildTypes {
- debug {
- //启用代码混淆
- minifyEnabled true
- //混淆规则配置文件
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- //
- signingConfig signingConfigs.debug
- }
- release {
- //是否优化zip
- zipAlignEnabled true
- // 移除无用的resource文件
- shrinkResources true
- //启用代码混淆
- minifyEnabled true
- //混淆规则配置文件
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- //
- signingConfig signingConfigs.release
- }
- }
三.混淆模版:
proguard-rules.pro:1、基本混淆(通用的混淆文件);2、运行混淆(自己打包混淆报错,然后使用keep忽略这些错误);3、第三方混淆(引入第三方包提供的混淆代码)
- # Add project specific ProGuard rules here.
- # By default, the flags in this file are appended to flags specified
- # in /Users/zst/Library/Android/sdk/tools/proguard/proguard-android.txt
- # You can edit the include path and order by changing the proguardFiles
- # directive in build.gradle.
- #
- # For more details, see
- # http://developer.android.com/guide/developing/tools/proguard.html
- # Add any project specific keep options here:
- # If your project uses WebView with JS, uncomment the following
- # and specify the fully qualified class name to the JavaScript interface
- # class:
- #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
- # public *;
- #}
- #############################################
- #
- # 对于一些基本指令的添加
- #
- #############################################
- # 代码混淆压缩比,在0~7之间,默认为5,一般不做修改
- -optimizationpasses 5
- # 混合时不使用大小写混合,混合后的类名为小写
- -dontusemixedcaseclassnames
- # 指定不去忽略非公共库的类
- -dontskipnonpubliclibraryclasses
- # 这句话能够使我们的项目混淆后产生映射文件
- # 包含有类名->混淆后类名的映射关系
- -verbose
- # 指定不去忽略非公共库的类成员
- -dontskipnonpubliclibraryclassmembers
- # 不做预校验,preverify是proguard的四个步骤之一,Android不需要preverify,去掉这一步能够加快混淆速度。
- -dontpreverify
- # 保留Annotation不混淆
- -keepattributes *Annotation*,InnerClasses
- # 避免混淆泛型
- -keepattributes Signature
- # 抛出异常时保留代码行号
- -keepattributes SourceFile,LineNumberTable
- # 指定混淆是采用的算法,后面的参数是一个过滤器
- # 这个过滤器是谷歌推荐的算法,一般不做更改
- -optimizations !code/simplification/cast,!field/*,!class/merging/*
- #############################################
- #
- # Android开发中一些需要保留的公共部分
- #
- #############################################
- # 保留我们使用的四大组件,自定义的Application等等这些类不被混淆
- # 因为这些子类都有可能被外部调用
- -keep public class * extends android.app.Activity
- -keep public class * extends android.app.Appliction
- -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 * extends android.view.View
- -keep public class com.android.vending.licensing.ILicensingService
- # 保留support下的所有类及其内部类
- -keep class android.support.** {*;}
- # 保留继承的
- -keep public class * extends android.support.v4.**
- -keep public class * extends android.support.v7.**
- -keep public class * extends android.support.annotation.**
- # 保留R下面的资源
- -keep class **.R$* {*;}
- # 保留本地native方法不被混淆
- -keepclasseswithmembernames class * {
- native <methods>;
- }
- # 保留在Activity中的方法参数是view的方法,
- # 这样以来我们在layout中写的onClick就不会被影响
- -keepclassmembers class * extends android.app.Activity{
- public void *(android.view.View);
- }
- # 保留枚举类不被混淆
- -keepclassmembers enum * {
- public static **[] values();
- public static ** valueOf(java.lang.String);
- }
- # 保留我们自定义控件(继承自View)不被混淆
- -keep public class * extends android.view.View{
- *** get*();
- void set*(***);
- public <init>(android.content.Context);
- public <init>(android.content.Context, android.util.AttributeSet);
- public <init>(android.content.Context, android.util.AttributeSet, int);
- }
- # 保留Parcelable序列化类不被混淆
- -keep class * implements android.os.Parcelable {
- public static final android.os.Parcelable$Creator *;
- }
- # 保留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();
- }
- # 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆
- -keepclassmembers class * {
- void *(**On*Event);
- void *(**On*Listener);
- }
- # webView处理,项目中没有使用到webView忽略即可
- -keepclassmembers class fqcn.of.javascript.interface.for.webview {
- public *;
- }
- -keepclassmembers class * extends android.webkit.webViewClient {
- public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
- public boolean *(android.webkit.WebView, java.lang.String);
- }
- -keepclassmembers class * extends android.webkit.webViewClient {
- public void *(android.webkit.webView, jav.lang.String);
- }
- #############################################
- #
- # 运行错误
- #
- #############################################
- -keep class okhttp3.** { *; }
- -keep interface okhttp3.** { *; }
- -dontwarn okhttp3.**
- -keep class okio.** { *; }
- -keep interface okio.** { *; }
- -dontwarn okio.**
- -keep class com.hitomi.** { *; }
- -keep interface com.hitomi.** { *; }
- -dontwarn com.hitomi.**
- #############################################
- #
- # Android引入第三方包混淆
- #
- #############################################
- ##图片加载
- # glide
- -keep public class * implements com.bumptech.glide.module.GlideModule
- -keep public class * extends com.bumptech.glide.module.AppGlideModule
- -keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
- **[] $VALUES;
- public *;
- }
- # glide for DexGuard only
- # -keepresourcexmlelements manifest/application/meta-data@value=GlideModule
- ## 图片剪切
- -dontwarn com.yalantis.ucrop**
- -keep class com.yalantis.ucrop** { *; }
- -keep interface com.yalantis.ucrop** { *; }
- ## 好看确认框
- -keep class cn.pedant.SweetAlert.Rotate3dAnimation {
- public <init>(...);
- }
- ## 选择器WheelPicker
- -keepattributes InnerClasses,Signature
- -keepattributes *Annotation*
- -keep class cn.qqtheme.framework.entity.** { *;}
- ## 百度地图
- -keep class com.baidu.** {*;}
- -keep class vi.com.** {*;}
- -dontwarn com.baidu.**
- ## 一个开源gif控件-配合简单下拉刷新下拉动画
- -keep public class pl.droidsonroids.gif.GifIOException{<init>(int);}
- -keep class pl.droidsonroids.gif.GifInfoHandle{<init>(long,int,int,int);}
- ## 阿里云
- -keep class com.taobao.** {*;}
- -keep class com.alibaba.** {*;}
- -dontwarn com.taobao.**
- -dontwarn com.alibaba.**
- -keep class com.ut.** {*;}
- -dontwarn com.ut.**
- -keep class com.ta.** {*;}
- -dontwarn com.ta.**
- ## 友盟
- -keep class com.umeng.commonsdk.** {*;}
四:开发报错
1、报错如下
- Warning:okhttp3.CacheControl: can't find referenced class javax.annotation.Nullable
- Warning:okhttp3.Address: can't find referenced class javax.annotation.Nullable
- Warning:okio.AsyncTimeout: can't find referenced class javax.annotation.Nullable
- Warning:okio.Buffer: can't find referenced class javax.annotation.Nullable
- Warning:okio.BufferedSource: can't find referenced class javax.annotation.Nullable
- Warning:okio.ByteString: can't find referenced class javax.annotation.Nullable
- Warning:com.hitomi.glideloader.GlideImageLoader: can't find referenced class com.bumptech.glide.DrawableTypeRequest
- Warning:com.hitomi.glideloader.GlideImageLoader: can't find referenced class com.bumptech.glide.DrawableRequestBuilder
- Warning:com.hitomi.glideloader.GlideImageLoader: can't find referenced class com.bumptech.glide.DrawableTypeRequest
- Warning:com.hitomi.glideloader.GlideImageLoader: can't find referenced class com.bumptech.glide.DrawableRequestBuilder
解决
- #############################################
- #
- # 运行错误
- #
- #############################################
- -keep class okhttp3.** { *; }
- -keep interface okhttp3.** { *; }
- -dontwarn okhttp3.**
- -keep class okio.** { *; }
- -keep interface okio.** { *; }
- -dontwarn okio.**
- -keep class com.hitomi.** { *; }
- -keep interface com.hitomi.** { *; }
- -dontwarn com.hitomi.**
2、报错如下
- Warning:Exception while processing task java.io.IOException: Can't write [E:\project-gitosc\pet\Pet-Android\Pet-Bulter\app\build\intermediates\transforms\proguard\release\jars\3\1f\main.jar] (Can't read [C:\Users\BF100232\.android\build-cache\9ea435c6c64b596437b8a78dad29fee1b093231b\output\jars\classes.jar(;;;;;;**.class)] (Duplicate zip entry [classes.jar:android/support/design/widget/CoordinatorLayout$LayoutParams.class]))
- Error:Execution failed for task ':app:transformClassesAndResourcesWithProguardForRelease'.
- > Job failed, see logs for details