Android开发之混淆基础教程

2025-10-24 04:38:16

1、在android 2.3以前,混淆Android代码只能手动添加proguard来实现代码混淆,非常耻眠不方便。而2.3以后,Google已经将这个工具加入到了SDK的工具集里。具体路径:SDK\tools\proguard。当使用Android Studio创建一个新的module时,在module的根目录下,自动创建名为proguard-rules.pro的配置文件。

Android开发之混淆基础教程

2、Android Studio在打包签名的apk文件时,默认未开启混淆功能,打开module根目录下的build.gradle文件,将minifyEnabled false修改为minifyEnabled true,即可开启代码混淆功能。

Android开发之混淆基础教程

3、看到上图,混淆的文件包括:proguard-android.txt和proguard-rules.pro两个,前者当前读取SDK工具集Google默认提供的混淆规则,或者读取开发者自定义的混淆规则,如果开发者还不熟悉怎泛陕么书写自定义的混淆规则,proguard-rules.pro文件耻爬板不写入任何内容,然后签名打包apk文件,生成的apk文件使用了proguard-android.txt文件的规则混淆代码

4、未开启代码混淆的MainActivity.class,如下图:

Android开发之混淆基础教程

5、使用默认规则混淆的MainActivity.class,如下图:

Android开发之混淆基础教程

6、到此,完成了Android Studio如何开启代码混淆功能的学习

1、因为开启混淆后,默认混淆项目下的所有代码,所以混淆指定的包名、类名、方法名转变成保留指定的包名、类名、方法名,为什么这样设计?可能,考虑到保留的类总是比混淆的类少很多很多吧!

如果你想深入了解混淆的基础知识,可以参考SDK工具集混淆文档:sdk\tools\proguard\docs\index.html,你会发现,广义的混淆,包括代码压缩、代码优化和代码混淆,而本文所说的仅指代码混淆,广义的混淆,如下图:

Android开发之混淆基础教程

2、默认混淆项目下的包名、类名、方法名。如果阅读文档比较吃力,没有关系,可以继续往下看,TeachCourse将文档涉及部分知识点以例子的方式进行演示。在上面创建的module项目中,新建一个类User类,并添加对应的属性、方法,项目结构如下图:

Android开发之混淆基础教程

3、User的代码结构如下图:

Android开发之混淆基础教程

4、因为开启混淆后,默认混淆项目下的所有代码,新建的User类、User类方法名和User类包名都会被混淆,因此我们不需要在proguard-rules.pro添加任何规则,签名打包apk文件,进行反编译后查看源码,项目结构如下图:

Android开发之混淆基础教程

5、保留指定的包名。在User包名下新建City类,该类包含latitude、longitude、cityName三个属性,代码如下:

Android开发之混淆基础教程

6、保留City的包名,在proguard-rules.pro文件添加如下规则:

Android开发之混淆基础教程

7、反编译签名打包的apk,项目结构如下图:

Android开发之混淆基础教程

8、保留指定的类名。在保留包名的前提下,继续保留City类名,在proguard-rules.pro文件添加如下规则:

Android开发之混淆基础教程

9、反编译签名打包的apk,项目结构如下图:

Android开发之混淆基础教程

10、打开这时候的City,各个方法名已被混淆,如下图:

Android开发之混淆基础教程

11、保留指定的方法名。在保留包名、类名的前提下,继续保留City指定的方法,比如:保留所有的get方法,在proguard-rules.pro文件添加如下规则:

Android开发之混淆基础教程

12、反编译签名打包的apk,项目结构如下图:

Android开发之混淆基础教程

13、到此,完成了混淆指定包名、类名和方法名部分的学习,虽然不算全面的,但对于理解混淆的过程还是比较有帮助的。

1、一个项目通常包含不少的包名、类名以及一个类里面也包含不少的方法,如果一个个指定必然是件繁琐的工作,比如,我想要保留当前demo包名cn.teachcourse下所有代码(包含bean、obfuscateapplication子目录),那保留的规则怎么写呢?如果在子目录obfuscateapplication再添加子目录common、main子目录,那保留的规则又该怎么写呢?项目结构目录如下图:

Android开发之混淆基础教程

2、混淆一组包名。在上面目录结构的基础上,保留cn.teachcourse目录下的所有子目录,在proguard-rules.pro文件添加如下规则:

Android开发之混淆基础教程

3、预测的效果:保留bean子目录和obfuscateapplication子目录及其下一级子目录。

反编译签名打包的apk,项目结构和上图是一样的,如下图:

Android开发之混淆基础教程

4、现在,我想要混淆common、main子目录,同时保留bean、obfuscateapplication,在proguard-rules.pro文件添加如下规则:

Android开发之混淆基础教程

5、预期的效果:保留cn.teachcourse的下一级子目录,比如:bean和obfuscateapplication子目录,混淆第二级以下的子目录,比如:common和main子目录。

反编译签名打包的apk,项目结构如下图:

Android开发之混淆基础教程

6、纳尼?common和main子目录竟然没有被混淆,难道proguard-rules.pro写入的混淆规则不正确?

不可能呀!为了验证什么原因,在bean目录下添加子目录serialbean,项目结构如下图:

Android开发之混淆基础教程

7、重新反编译签名打包的apk,项目结构如下图:

Android开发之混淆基础教程

8、serialbean子目录已经混淆,但common和main子目录仍然保留。

其实,添加上述规则,可以混淆cn.teachcourse包名下的第二级及其以下的目录,因为BaseActivity和MainActivity继承自四大组件之一的Activity,系统默认不混淆四大组件所在目录以及组件的名称,所以会出现上述情况。

9、如果,我们在common和main子目录存放非四大组件的代码,毫无疑问,这时候的子目录会被混淆,不信,请看下图:

Android开发之混淆基础教程

10、反编译后的目录结构:

Android开发之混淆基础教程

11、到此,完成了一组包名混淆的两条规则:

Android开发之混淆基础教程

12、混淆一组类名。现在,我想要保留City和City2或者User和User2,保留规则又该怎么写呢?在proguard-rules.pro文件中添加如下规则:

Android开发之混淆基础教程

13、反编译签名打包的apk,混淆结构如下图:

Android开发之混淆基础教程

14、现在,CityBean和UserBean都实现了Serializable接口,我想要同时保留实现序列化接口的实体,保留规则又该怎么写呢?在proguard-rules.pro文件中添加如下规则:

Android开发之混淆基础教程

Android开发之混淆基础教程

15、反编译apk文件,项目结构图如下:

Android开发之混淆基础教程

16、同理,如果想要同时保留多个继承类,比如:继承View,你需要在proguard-rules.pro添加如下规则:

Android开发之混淆基础教程

17、突然,想到一个问题,如果想要保留内部类,比如:Student类包含静态嵌套类Builder,想要保留嵌套类,保留规则该怎么写?Student包含的代码如下:

Android开发之混淆基础教程

Android开发之混淆基础教程

18、在proguard-rules.pro文件中添加如下规则:

Android开发之混淆基础教程

19、反编译签名打包的apk,保留嵌套类的代码结构如下图:

Android开发之混淆基础教程

20、到此,完成了保留一组类名的学习,添加的规则包含以下几种:

Android开发之混淆基础教程

21、混淆一组方法名。因为开启混淆后,默认混淆项目下的所有代码,所以混淆一组方法名,实质也是保留一组方法名,保留的方法名包括:构造方法、成员方法、类方法

在混淆一组类名中,提到了保留所有继承自View的子类,在此我们增加保留所有子类中添加的构造方法,在proguard-rules.pro文件中添加如下规则:

Android开发之混淆基础教程

22、如果想要同时保留继承自View子类的所有set方法,在proguard-rules.pro文件中添加如下规则:

Android开发之混淆基础教程

23、为了验证,如何保留类方法,在原来City类的基础上添加如下代码:

Android开发之混淆基础教程

24、默认情况,类方法from()会被混淆,现在想要将其保留下来,需要在proguard-rules.pro文件中添加如下规则:

Android开发之混淆基础教程

25、反编译签名打包的apk,查看City源码结构如下图:

Android开发之混淆基础教程

26、到此,完成了保留一组方法名的学习,添加的规则包含以下几种:

Android开发之混淆基础教程

1、保留一组包名、类名、方法名是在保留指定包名、类名、方法名的基础上添加一些通配符,这些通配符以及通配符的含义如下:

1、%,匹配任意私有类型,比如:boolean、int,但不包括void

2、?,匹配一个类名中的单个字符

3、*,匹配不包含包名分隔符(.)的多个字符

4、**,匹配包含包名分隔符(.)的多个字符

5、***,匹配任意的类型(私有的或非私有的,数组或非数组)

6、...,匹配多个参数的任意类型

7、<init>,匹配任意的构造方法

8、<fields>,匹配任意的字段

9、<methods>,匹配任意的方法

用于保留包名的关键字是-keeppackagenames,用于保留类名和用于保留方法名的关键字及其含义总结如下:

Android开发之混淆基础教程

2、Android Studio开启混淆功能后,除了系统保留的代码外,默认混淆所有的代码,广义的混淆包括压缩、优化、混淆,没有被引用的代码开启混淆后会自动被删除,这也是我为什么在MainActivity类引用各个类的原因。

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢