大家好,又见面了,我是你们的朋友全栈君。
一、前言
为何需要混淆呢?简单的说,就是将原本正常的项目文件,对其类,方法,字段,重新命名,a,b,c,d,e,f…之类的字母,达到混淆代码的目的,这样反编译出来,结构乱糟糟的,看了也头大。
另外说明一下,本文的混淆总结基于Android Studio的IDE开发环境。
二、官方默认的混淆配置
其实在android Studio中做混淆,基本就是对Proguard-rules.pro文件的操作。混淆的过程也是有规律可循的。先看看官方的proguard-android.txt文件,位于/tools/proguard目录下,不知道怎么写,可以当成模板,复制一份出来到自己的工程,改成自己项目所需的混淆配置。内容如下:
# This is a configuration file for ProGuard. # http://proguard.sourceforge.net/index.html#manual/usage.html -dontusemixedcaseclassnames -dontskipnonpubliclibraryclasses -verbose # Optimization is turned off by default. Dex does not like code run # through the ProGuard optimize and preverify steps (and performs some # of these optimizations on its own). -dontoptimize -dontpreverify # Note that if you want to enable optimization, you cannot just # include optimization flags in your own project configuration file; # instead you will need to point to the # "proguard-android-optimize.txt" file instead of this one from your # project.properties file. -keepattributes *Annotation* -keep public class com.google.vending.licensing.ILicensingService -keep public class com.android.vending.licensing.ILicensingService # For native methods, see http://proguard.sourceforge.net/manual/examples.html#native -keepclasseswithmembernames class * { native <methods>; } # keep setters in Views so that animations can still work. # see http://proguard.sourceforge.net/manual/examples.html#beans -keepclassmembers public class * extends android.view.View { void set*(***); *** get*(); } # We want to keep methods in Activity that could be used in the XML attribute onClick -keepclassmembers class * extends android.app.Activity { public void *(android.view.View); } # For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); } -keepclassmembers class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator CREATOR; } -keepclassmembers class **.R$* { public static <fields>; } # The support library contains references to newer platform versions. # Don't warn about those in case this app is linking against an older # platform version. We know about them, and they are safe. -dontwarn android.support.** # Understand the @Keep support annotation. -keep class android.support.annotation.Keep -keep @android.support.annotation.Keep class * {*;} -keepclasseswithmembers class * { @android.support.annotation.Keep <methods>; } -keepclasseswithmembers class * { @android.support.annotation.Keep <fields>; } -keepclasseswithmembers class * { @android.support.annotation.Keep <init>(...); }
这个混淆默认采取一些通用的规则,view,activity,Parcelable,注解,R文件,枚举这类的东西都不会混淆,我们也不能混淆这些,否则release版本会报错。
三、Android Studio开启混淆配置
很简单,只要设置minifyEnabled为true即可。
buildTypes {
release {
minifyEnabled true//true开启混淆配置,false关闭
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.duqian_android_keystore
}
debug{//省略}
}
四、Android混淆的通用规则
1. 系统混淆配置
-dontusemixedcaseclassnames #混淆时不使用大小写混合类名
-dontskipnonpubliclibraryclasses #不跳过library中的非public的类
-verbose #打印混淆的详细信息
-dontoptimize #不进行优化,建议使用此选项,
-dontpreverify #不进行预校验,Android不需要,可加快混淆速度。
-ignorewarnings #忽略警告
#-optimizationpasses 5 #指定代码的压缩级别
2. 常用的一些混淆配置
-keepattributes Signature #范型 #native方法不混淆 -keepclasseswithmembernames class * { native <methods>; } #v4包不混淆 -keep class android.support.v4.app.** { *; } -keep interface android.support.v4.app.** { *; } #Gson混淆配置 -keep class sun.misc.Unsafe { *; } -keep class com.idea.fifaalarmclock.entity.*** -keep class com.google.gson.** { *; } #JavaBean -keepclassmembers public class cn.net.duqian.bean.** { void set*(***); *** get*(); } -keep class com.xx.duqian_cloud.JavaScriptInterface { *; }#webview js #忽略 libiary 混淆 -keep class io.vov.vitamio.** { *; } #butterknife不混淆 -keep class butterknife.** { *; } -dontwarn butterknife.internal.** -keep class **$$ViewBinder { *; } -keepclasseswithmembernames class * { @butterknife.* <fields>; } -keepclasseswithmembernames class * { @butterknife.* <methods>; }
3. 第三方框架一般不混淆(但也要看具体情况)
-keepclassmembers class * { public <init> (org.json.JSONObject); } #okhttp -dontwarn okhttp3.** -keep class okhttp3.**{*;} -keep interface okhttp3.**{*;} #okio -dontwarn okio.** -keep class okio.**{*;} -keep interface okio.**{*;} -dontwarn retrofit2.** -keep class retrofit2.** { *; } -keepattributes Signature -keepattributes Exceptions -dontwarn rx.** -keep class rx.**{*;}
四、Android混淆的方法和通配符对照表
五、不能混淆的情况总结
- Java的反射,为什么不能混淆呢?因为代码混淆,类名、方法名、属性名都改变了,而反射它还是按照原来的名字去反射,结果只射出一个程序崩溃
- 注解用了反射,所以不能混淆。 不混淆任何包含native方法的类的类名以及native方法名,否则找不到本地方法。
- Activity不能混淆,因为AndroidManifest.xml文件中是完整的名字
- 自定义view也是带了包名写在xml布局中,不能混淆
六、混淆后使用时常见问题
当项目中出现so的native代码找不到Java的方法的时候,可以尝试将
-keepclasseswithmembernames class * { native <methods>; }
更改为:
-keep class * { native <methods>; }
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/154868.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...