学习混淆的最终目的:希望运用到当前开发的Android项目中,那么Android项目需要添加的混淆规则包括哪些呢?在《Android开发之混淆基础教程》介绍了混淆指定包名、指定类名和指定方法的基础知识,《Android开发之混淆高级教程01》介绍了保留关键字-keep之间的区别,本篇文章主要介绍第三方类库、注解、序列化对象、实体、自定义View、枚举、native方法、callback方法、JS交互方法等混淆规则的写法,最后总结成一份可以通用的Android项目混淆规则。
工具/原料
- IDE开发工具:Android Studio
- 反编译工具:apktool、dex2jar、jd-gui
一、Android项目混淆规则分类
-
在学习了Android开发之混淆基础教程,知道怎么保留指定的包名、类名、方法名以及字段后,其实已经掌握了混淆的大部分内容。为了更好地运用、记忆混淆的内容,将混淆规则划分成如下几类:
-
1.1 混淆第三方类库
怎么混淆第三方类库,这是一个很多同学可能会问的问题,因为我们并不是类库的开发者,对于类库的代码、结构不熟悉,自然不知道该添加什么样的混淆规则,这是比较头疼的事情。对于我个人来说,能够添加混淆规则的第三方类库,尽量添加,混淆其中一个好处压缩apk的大小,减少内存的消耗。
一个优秀的开源项目,开发者可能会提供对应的混淆规则,所以,添加第三方类库的混淆规则,第一种方法:登录GitHub或开源库官网,查找开源库的混淆规则,直接复制到当前Android项目中即可,查看当前项目添加的第三方类库,如下图:
步骤阅读
-
以com.squareup.okhttp3:okhttp:3.8.1类库为例,在GitHub搜索开源库okhttp,查看混淆规则说明,如下所示:
步骤阅读
-
直接复制上述规则,到我们当前开发的Android项目中即可。
如果第三方类库,开发者没有提供对应的混淆规则,哪该怎么办?以com.nineoldandroids:library:2.4.0为例,在GitHub查看开源库,没有找到混淆规则的代码,如果比较熟悉开源库的源码,可以自己定义开源库的混淆规则,但如果你还没有阅读过源码,不知道怎么写混淆规则,建议可以保留开源库,不混淆包名下(二级、三级及其以下)的所有文件,如下图:
步骤阅读
-
在当前Android项目中,添加如下规则:
步骤阅读
-
混淆第三方类库,第一种方法:复制开源库的混淆规则到项目中,第二种方法:保留开源库包名及其以下所有类、方法,第三种方法:自己定义开源库的混淆规则,前提是熟悉开源库源码
-
1.2 混淆注解相关代码
这里所说的注解,不包括第三方类库使用到注解,使用注解的第三方类库,可以参考混淆第三方类库的方法。
保留注解相关代码,需要使用关键字-keepattributes [attribute_filter],该关键字的作用:指定需要被保留的任一可选项属性,属性可以指定一项或多项,可以选择的属性attribute_filter包括如下几种类型:
-
1、Exceptions
2、Signature
3、Deprecated
4、SourceFile
5、SourceDir
6、LineNumberTable
7、LocalVariableTable
8、LocalVariableTypeTable
9、Synthetic
11、EnclosingMethod
12、RuntimeVisibleAnnotations
13、RuntimeInvisibleAnnotations
14、RuntimeVisibleParameterAnnotations
15、RuntimeInvisibleParameterAnnotations
16、AnnotationDefault
-
混淆注解的相关代码,需要在Android项目中,添加如下规则:
步骤阅读
-
1.3 混淆序列化对象(Serializable、Parcelable)
继承自Serializable或Parcelable接口的类创建的对象称为序列化对象,为什么需要保留序列化对象的某些字段、方法,需要深入了解序列化的特点。
序列化对象以字节的形式保留到本地或在网络中传输,再通过反序列化将获取的字节重新组装成对象,为了保证组装的成功
-
1.3.1 混淆实现Serializable接口的类
1、需要保留的字段包括:非static、非transient、非private修饰的字段
2、需要保留的方法包括:非private修饰的方法,writeObject()方法、readObject()方法、writeReplace()方法、readResolve()方法
混淆实现Serializable接口的类,在当前Android项目中,添加如下规则:
步骤阅读
-
1.3.2 混淆实现Parcelable接口的类
混淆实现Parcelable接口的类,在当前Android项目中,添加如下规则:
步骤阅读
-
1.4 混淆实体类
我刚开始学习Android的时候,容易把实体对象、序列化对象弄错,实体类和序列化类的一个重要区别是:前者没有实现Serializable接口,无法持久化对象。
实体对象和序列化对象的相同特点:
1、使用private定义属性字段
2、提供set和get方法设置、访问属性字段
3、提供空的构造方法
-
1.4.2 序列化类
步骤阅读
-
1.4.2 序列化类
步骤阅读
-
混淆实体类,在当前Android项目中添加如下规则:
PS:在你的Android项目中,需要将cn.teachcourse.bean目录改为你存放实体的路径。
步骤阅读
-
1.5 混淆自定义View
重写继承自View或ViewGroup的方法,实现需要的效果,为了保证自定义的View可以布局文件中正常引用,不运行混淆自定义View:构造方法、set方法、get方法等
混淆自定义View,在当前Android项目中添加如下规则:
步骤阅读
-
1.6 混淆枚举类
什么是枚举?什么怎样在实际项目中应用?如果你不是很熟悉,可以先花两分钟大略阅读《Android开发之枚举(Enum)在实际项目中的应用》
混淆枚举类,在当前Android项目中添加如下规则:
步骤阅读
-
1.7 混淆native方法
一个native关键字修饰的方法,称为native方法,一个native方法长得很像abstract方法:只有方法签名,没有方法体,与抽象方法不同的是:native方法是由非Java语言实现的,比如C/C++语言实现;abstract方法是由Java语言实现的,下面是一个包含native方法的例子:
步骤阅读
-
1.7.1 native方法实现的过程:
1、编写Java程序,javac编译生成.class文件;
2、用javah编译生成的class文件,生成.h文件;
3、编写.cpp文件实现native方法,其中需要包含上述生成.h文件(.h文件包含了JDK自带的jni.h文件);
4、将.cpp文件变异成动态链接库.dll文件;
5、在Java中调用System.loadLibrary()方法或Runtime.loafLibrary()方法加载动态链接库文件,实现在Java中调用这个native方法;
6、运行Java文件:java Djava.library.path=[dll存放的路径]。
混淆native方法,在当前Android项目中添加如下规则:
步骤阅读
-
1.8 混淆callback方法
什么是callback方法呢?简单地说小明想要计算1024+1024等于多少的填空题,但因为小明还没学过四位数的加法,于是借助计算器的帮助,最终,小明得出1024+1024的答案,完成填空题,代码如下:
步骤阅读
-
1.8.1 callback方法
步骤阅读
-
类Student持有SuperCalculator的引用,在A类中调用B类的方法;同时SuperCalculator也持有Student的引用,B类将计算结果通过A类的方法,回调给A类,在上面的例子中,fillBlank()就是一个callback方法。
-
1.8.2 不陌生的callback方法
有接口的地方,就用到callback方法,这样的例子有很多,比如:列表选择、手势拖拽、焦点改变、按钮点击,这里看一下按钮点击的回调方法,代码如下:
步骤阅读
-
在上面点击按钮的例子中,我们想要保留callback方法setTextSieze(),在当前Android项目中添加如下规则:
步骤阅读
-
1.9 混淆JS交互方法
为什么需要JS交互方法?在需要与H5进行JS交互的界面,前端根据Android客户端传递的对象,调用相关的方法,比如:页面开始加载方法onPageStarted()、页面加载结束方法onPageFinished()以及页面重载方法shouldOverrideUrlLoading(),上述方法来自android.webkit.WebViewClient类,也就是说为了保证WebView加载H5界面可以正确WebViewClient的方法,在proguard-rules.pro添加如下规则:
步骤阅读
-
除此之外,我们会自定义JS可以调用的方法,如下图:
步骤阅读
-
我们在当前加载H5网页的activity中,定义isLogin()方法,在点击H5按钮,兑换积分礼品,这时通过JS代码,在H5界面调用Java代码中的isLogin(),判断用户是否登录,我们需要保留所有JS会调用的Java代码,在proguard-rules.pro添加如下规则:
步骤阅读
-
PS:LoginInterface是定义的一个接口,声明了H5界面会调用的方法,在你的Android项目中,需要修改成你自己的类。
END
二、总结
-
本篇文章通过例子的方式说明:第三方类库、注解、序列化对象、实体、自定义View、枚举、native方法、callback方法、JS交互方法规则的写法,当然在Android项目中,需要混淆的内容还不止这些分类,在熟悉了混淆基础知识的前提下,想要保留任意的包名、类名、方法名以及字段,都不是问题,将上面的规则总结如下:
步骤阅读
步骤阅读
步骤阅读
步骤阅读
END
注意事项
- 本篇文章重点总结了Android项目混淆的多个方面,但还不算全面
- 根据保留的内容划分,可能彼此存在交叉的混淆规则,使用的时候,按照上述顺序制定
本文来自投稿,不代表幸运快三立场,转载请注明出处:http://www.morucat.com/digital/8478.html