2016 - 2024

感恩一路有你

Android开发之混淆高级教程:压缩阶段

浏览量:2355 时间:2024-01-21 19:20:25 作者:采采

上一篇文章介绍了混淆的基础知识,包括保留指定的包名、类名、方法名以及字段名。本篇文章将重点介绍混淆的广义概念,包括压缩、优化和混淆几个阶段。

1. 压缩阶段

在Java编译时,源代码(.java)会被转换成字节码(.class),相比源代码,字节码更加简洁。然而,生成的字节码中可能包含一些没有用到的代码,特别是当项目中使用了第三方类库时,未引用的代码会更多。

压缩阶段会分析生成的字节码,在确保项目正常运行的同时移除一些未引用的类、字段和方法。为了验证移除未引用代码的效果,我们创建一个module,包含AdvancedCourseActivity和Subject两个类,其中Subject没有被引用。

对混淆后的项目进行签名打包,并反编译生成的apk文件,检查是否仍然存在Subject的字节码文件。

2. 反编译结果

反编译后的项目结构如下:

由以上结果可见,Subject的字节码文件已被成功移除。

3. 引用代码

接下来我们修改Subject类中的代码如下:

然后在AdvancedCourseActivity中引用Subject提供的构造方法和get方法。我们想知道未被引用的set方法是否会被移除。

4. 反编译结果再次分析

反编译后的项目结构如下:

从以上结果可见,混淆后仅保留了被引用的字段(courseName、creditHour)和方法(getCourseName()、getCreditHour()),以及构造方法。我们将在后续的混淆中巧妙地使用压缩规则,类似于Android Studio的App Link Assistant功能。

那么,如果我们不想执行代码的压缩,该怎么做呢?这时候,我们需要学习一些压缩阶段的规则(除此之外,还有优化规则和混淆规则)。

压缩规则的可选项包括以下几种:

1. -dontshrink:开启混淆,默认压缩所有类。通过添加该关键字,可关闭压缩过程。在文件中添加以下规则:

5. 反编译结果再次分析

反编译后的项目结构如下:

由上图可见,压缩阶段已被关闭,Subject的字节码文件仍然存在。

2. -printusage [filename]:将压缩阶段未引用的所有类信息打印到指定文件中。如果未在中指定该选项,则默认输出到路径:

在上述示例中,Subject的set方法未被引用,在usage.txt文件中可以找到相关信息。这一功能可用于检查签名打包后,在压缩阶段移除了哪些代码,并验证是否符合要求。

3. -whyareyoukeeping class_specification:打印保留类和内部成员的详细说明。class_specification指定需要了解的类名。详细说明将在Gradle控制台查看。例如,我们想了解为什么保留Subject类信息,可在文件中添加以下规则:

运行当前项目后,Gradle控制台将显示如下信息:

以上信息表明Subject类被引用了setCourseName()和setCreditHour()方法,以及get方法和构造方法。在AdvancedCourseActivity的void onCreate()方法中进行了调用。

至此,我们完成了压缩阶段的学习。

版权声明:本文内容由互联网用户自发贡献,本站不承担相关法律责任.如有侵权/违法内容,本站将立刻删除。