本文旨在帮助初学者快速掌握Android混淆的基本操作,内容涵盖在Android Studio中如何开启混淆功能,以及针对特定包名、类名和方法名进行混淆的配置方法,同时介绍常用通配符的使用规则。通过本教程可打下扎实基础,适合尚未熟悉混淆流程的开发者学习。若希望进一步提升技能,可延伸阅读Android开发之混淆高级教程以获取更深入的知识。
1、 在Android 2.3版本之前,若要对代码进行混淆处理,必须手动集成ProGuard工具,操作较为繁琐。自Android 2.3起,Google已将ProGuard集成进SDK工具包中,位于SDK目录下的tools/proguard路径。此后,在使用Android Studio新建一个模块时,系统会自动在该模块的根目录下生成一个名为proguard-rules.pro的配置文件,用于编写混淆规则,极大简化了代码混淆的配置流程,提升了开发效率与安全性。
2、 在使用Android Studio生成签名APK时,默认情况下代码混淆功能处于关闭状态。若需启用,可进入项目中对应模块的根目录,找到build.gradle文件,将其中的minifyEnabled false修改为minifyEnabled true,然后同步项目配置,即可开启代码混淆,从而提升应用的安全性与压缩效果。
3、 如上图所示,涉及的混淆文件主要有两个:proguard-android.txt 和 proguard-rules.pro。其中,proguard-android.txt 默认由 Google 提供,位于 Android SDK 工具目录中,包含了基础的代码混淆规则,也可被开发者自定义规则替代。而 proguard-rules.pro 是项目中用于编写额外混淆配置的文件。若开发者尚未掌握自定义混淆规则的编写方法,可保持该文件为空。在构建应用时,即使 proguard-rules.pro 无内容,系统仍会自动采用 proguard-android.txt 中的默认规则对代码进行混淆处理。最终生成的 APK 文件中的代码将依照这些默认规则完成混淆,从而达到基本的代码保护效果,无需手动干预即可实现初步的安全防护。
4、 未启用代码混淆时的MainActivity.class文件,所示。
5、 经默认规则混淆后的MainActivity.class文件,所示。
6、 至此,已掌握在Android Studio中启用代码混淆的方法。
7、 开启混淆后,默认会混淆所有代码,因此需明确保留特定包名、类名和方法名。这种设计可能是为了提高效率,因为需要保留的成员通常远少于需要混淆的成员,通过显式保留关键部分,可简化配置并减少出错可能。
8、 若想深入理解混淆的基本概念,可查阅SDK工具集中的混淆文档:sdktoolsproguarddocsindex.html。其中指出,广义上的混淆涵盖代码压缩、优化与混淆三个部分。本文所讨论的仅为代码混淆这一环节,具体构成所示。
9、 默认会对项目中的包名、类名及方法名进行混淆处理。若觉得文档理解起来有难度,不必担心,接下来的内容将通过具体示例帮助你掌握相关知识点。在之前创建的module中,新建一个名为User的类,并为其添加相应的属性和方法,整体项目结构所示。
10、 用户代码结构所示。
11、 开启混淆后,默认会对项目中所有代码进行混淆处理,包括新建的User类、其方法名以及所属包名均会被自动混淆。因此,无需在proguard-rules.pro文件中额外添加保留规则。在完成签名打包并生成APK后,通过反编译查看其源码,可观察到项目的结构已发生相应变化,具体所示。
12、 在User包中创建City类,包含latitude、longitude和cityName三个属性,具体代码实现如下:
13、 在proguard-rules.pro文件中添加相应规则,同时保留City的包名不被混淆。
14、 反编译已签名的APK文件,其项目结构所示。
15、 在 proguard-rules.pro 文件中,保留指定包名及 City 类名,添加相应规则以防止混淆,确保该类在代码压缩与优化过程中保持不变。
16、 反编译已签名的APK文件,项目结构所示。
17、 此时打开City,可见各方法名均已混淆,所示。
18、 在 proguard-rules.pro 文件中添加如下规则:保留指定包名和类名下的 City 类及其所有 get 方法,确保指定方法名不被混淆,维持原有功能调用。
19、 反编译已签名的APK,项目结构所示。
20、 至此,已学习完包名、类名及方法名的混淆内容,虽不够全面,但对理解混淆机制仍具指导意义。
21、 一个项目往往包含多个包名和类名,而每个类中又可能定义了大量方法。若逐一指定需要保留的内容,过程将十分繁琐。例如,希望保留当前 demo 中包名 cn.teachcourse 及其所有子目录(如 bean、obfuscateapplication)下的全部代码,应如何编写保留规则?进一步地,若在 obfuscateapplication 子目录下新增 common 和 main 两个子目录,原有的保留规则是否仍适用,又该如何调整?面对不断变化的项目结构,如何制定灵活且高效的保留策略?项目整体的目录结构所示,需根据层级关系合理配置规则,确保所有必要内容均被正确保留,避免遗漏或重复配置,提升维护效率。
22、 对包名进行混淆处理。在保持cn.teachcourse目录及其所有子目录不变的前提下,向proguard-rules.pro文件中添加相应的混淆规则,确保指定目录结构不被混淆,其他内容按规则进行混淆操作。
23、 保留bean目录及obfuscateapplication目录,同时保留它们各自下一级的子目录。
24、 反编译已签名打包的APK,其项目结构与上图相同,具体所示。
25、 需混淆common与main子目录,同时保留bean和obfuscateapplication不被混淆。在proguard-rules.pro文件中添加相应规则,确保指定目录参与混淆处理,而特定类或包名保持原样,避免影响功能调用与反射操作。
26、 预期实现:保留cn.teachcourse的直接子目录,如bean和obfuscateapplication;对其二级及更深层次的子目录进行混淆处理,例如common和main等下级目录将被混淆,确保结构清晰的同时增强代码安全性,层级划分明确,保护核心逻辑不被轻易识别,提升整体防护能力。
27、 反编译已签名打包的APK,项目结构所示。
28、 奇怪,common和main子目录未被混淆,是proguard-rules.pro中的规则设置有问题吗?
29、 真奇怪!为查明原因,特意在bean目录下新建了serialbean子目录,项目结构已调整所示。
30、 重新反编译已签名打包的APK,项目结构所示。
31、 serialbean目录已被混淆处理,而common与main目录仍保持原样未作变动。
32、 添加这些规则后,会混淆cn.teachcourse包下第二级及更深层级的目录。由于BaseActivity和MainActivity均继承自四大组件中的Activity,而系统默认不会混淆四大组件所在的目录及其类名,因此导致了上述结果。这种机制确保了组件类在运行时能被正确识别和调用,避免因混淆引发的程序异常,同时也允许对非组件类进行有效混淆以增强代码安全性。
33、 若将非四大组件的代码放入common和main子目录,这些目录必然会被混淆,具体情形所示。
34、 反编译后文件夹的组织方式
35、 至此,已实现包名混淆的两项规则。
36、 若需保留City与City2或User与User2类名不被混淆,可在proguard-rules.pro文件中添加相应规则,明确指定这些类不参与混淆处理,确保其名称在打包后仍保持不变。
37、 反编译已签名打包的APK,其混淆结构所示。
38、 如今,CityBean与UserBean均已实现Serializable接口,若需同时保留这两个序列化实体类,应如何编写保留规则?可在proguard-rules.pro文件中加入相应的keep规则,确保这两个类在混淆过程中不被压缩或优化,完整保留其字段与方法,以保障序列化功能正常运行。
39、 反编译APK后得到的项目结构所示
40、 若需同时保留多个继承类,例如继承View,应在proguard-rules.pro文件中添加相应的保留规则,确保相关类不被混淆或移除。
41、 突然想到一个问题:若要保留内部类,例如Student类中包含静态嵌套类Builder,应如何编写保留规则才能确保该嵌套类不被移除?具体代码结构如下所示:
42、 在proguard-rules.pro中加入以下配置规则以优化代码混淆。
43、 反编译已签名打包的APK,保持嵌套类代码结构所示。
44、 至此,已掌握保留特定类名的方法,新增规则主要包括以下几类。
45、 对一组方法名进行混淆处理。由于启用混淆后会默认混淆整个项目的代码,因此混淆实际上等同于保留特定方法名,包括构造方法、成员方法和类方法,确保这些方法在混淆过程中不被改变。
46、 在混淆类名时,需保留所有继承自View的子类及其新增的构造方法。为此,在proguard-rules.pro文件中加入相应规则,确保这些类和构造函数不被混淆,维持正常调用。
47、 若需保留View子类所有set方法,在proguard-rules.pro中加入相应规则即可。
48、 在原有City类基础上,添加相应代码以验证并保留类方法。
49、 默认情况下,类的from()方法会被混淆处理。若需保留该方法,应在proguard-rules.pro文件中添加相应规则以防止混淆。
50、 反编译已签名的APK,查看City源码结构所示。
51、 至此,已掌握保留一组方法名的学习,新增规则主要包括以下几类。
52、 保留包名、类名和方法名时,可在指定名称基础上添加通配符,这些符号用于匹配多个名称,具体含义取决于其在命名结构中的位置和使用方式。
53、 匹配所有私有数据类型,如boolean、int等,但不包含void类型。
54、 匹配类名中任意一个字符
55、 匹配不含包名分隔符的多个字符,不包含点号。
56、 匹配包含包名分隔符(.)的多个字符。
57、 可匹配所有类型,包括私有、非私有及数组与非数组形式。
58、 匹配任意类型的多个参数
59、 匹配所有构造方法,包括任意类型的初始化函数。
60、 8、,可匹配所有字段内容
61、 匹配所有方法的通用方式
62、 保留包名使用-keeppackagenames关键字,保留类名和方法名则采用相应关键字,其具体含义如下所述。
63、 启用Android Studio的混淆功能后,默认会对所有非保留代码进行混淆处理。广义上的混淆包含代码压缩、优化和混淆三个步骤。未被引用的类或方法在混淆过程中会被自动移除,因此我在MainActivity中显式引用各个类,以防止它们被误删,确保功能正常运行。
https://soft.zol.com.cn/1094/10946944.html
soft.zol.com.cn
true
中关村在线
https://soft.zol.com.cn/1094/10946944.html
report
7840
本文旨在帮助初学者快速掌握Android混淆的基本操作,内容涵盖在Android Studio中如何开启混淆功能,以及针对特定包名、类名和方法名进行混淆的配置方法,同时介绍常用通配符的使用规则。通过本教程可打下扎实基础,适合尚未熟悉混淆流程的开发者学习。若希望进一步提升技...