什么是代码混淆呢?混淆就是对发布出去的程序进行重新组织和处理,使得处理后的代码与处理前代码完成相同的功能,而混淆后的代码很难被反编译,即使反编译成功也很难得出程序的真正语义
为什么要进行Android代码混淆?Android是基于Java的,Java源代码编译成中间“字节码”存储于class文件中,很容易被反编译成Java源代码。为了防止辛辛苦苦开发的东西轻易流失,就需要对将要发布出去的程序进行混淆。接下来切入今天的正题,Android代码混淆,可以参考上篇android应用的反编译(点击打开链接),加深对代码混淆要性的理解
Android混淆用到的工具:ProGuard,还具有代码优化的作用,工作方式:去除无效的代码,将代码中的类名、函数名替换为晦涩难懂的名字。只能混淆java代码,对其它的如资源文件等无影响,相关联的文件主要有proguard、proguard-project.txt、project.properties,如下图所示:
为什么要配置proguard-project.txt文件,如果不配置,启用混淆功能时会把所有的java代码混淆,而Android工程中有些代码是不能被混淆的,所以该文件配置的是哪些文件不能混淆。不能被混淆的文件主要有以下几类:a 引用的第三方jar,已经被第三方公司混淆,再次混淆的话,执行程序就会报找不到该jar中的类;b 用到泛型的类;c 用到反射的类; d 用到java和js交互的类
基本的配置有以下三种:1 不混淆该包中的所有类 -keep class com.alipay.android.app.** {*; }
2 忽略混淆引起的包中所有类产生的警告 -dontwarn com.alipay.android.app.**
3 表明当前是一个jar(需要对jar包中的所有包下的类进行1和2处理) -libraryjarslibs/pinyi n4j-2.5.0.jar
衍生配置如下:a 不混淆某个类的构造函数 -keepclassmembers
class
com.ticktick.example.Test {
public
void
setTestString(java.lang.String);
}
b 不混淆某个包中的特定类 -keep
class
com.ticktick.example.Test { * ; }
c 不混淆某个类的特定的函数 -keepclassmembers
class
com.ticktick.example.Test {
public
void
setTestString(java.lang.String);
}
d 不混淆某个类的子类 -keep
public
class
*
extends
com.ticktick.example.Test
e 不混淆某个接口的实现 -keep
class
* implementscom.ticktick.example.TestInterface {
public
static
final
com.ticktick.example.TestInterface$Creator *;
}
其它配置:-optimizationpasses 3
-dontusemixedcaseclassnames #混淆时不会产生形形色色的类名
-dontskipnonpubliclibraryclasses#指定不去忽略非公共的类库
-dontpreverify#不预校验
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*#优化
注意:根据以上并不能保证所有不该混淆的都有配置,可以通过运行程序,通过程序给出的错误log信息,在proguard-project.txt文件中补
充不需要混淆的配置,这样既能达到保护代码不泄露,又能优化程序并同时保证程序应有的功能运行正常
常见问题归类:1 用到afinal和gson jar包做,且已经做过jar防混淆处理,还需要对用到的实体进行防混淆配置
-keep class cn.gyyx.android.qibao.model.** {*; }
-dontwarn cn.gyyx.android.qibao.model.**
2 解决missing a type错误
#过滤泛型
-keepattributes Signature
-keep class sun.misc.Unsafe { *; }
#Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
3 过滤Javascript webview.addJavascriptInterface(this, "install");
this就是需要过滤的类
-keepclassmembers class cn.gyyx.android.qibao.context.fragment.servantchild.AppRecommendF ragment{
public *;
}
-keepattributes *Annotation*
-keepattributes *JavascriptInterface*
附上配置截图:供参考
以上所有配置完善后,签名打包一个apk,试着反编译查看程序源码,对照一下原工程的代码,就可以知道代码混淆的强大威力,经过混淆之后再也不用担心辛辛苦苦的代码被拿走了