Android代码混淆

常用混淆规则

#不混淆某个类
-keep public class com.webi.demo.TestClass {*;}

#不混淆某个包的所有类
-keep class com.webi.demo.** {*;}

#不混淆某个类的子类
-keep public class * extends com.webi.demo.TestClass {*;}

#不混淆某个接口的实现
-keep class * implements com.webi.demo.TestInterface {*;}

#不混淆某个类的特定方法
-keepclassmembers class com.webi.demo.TestClass{
    public void test(java.lang.String);
}

#不混淆某个类的内部类
-keep class com.webi.demo.TestClass$* {*;}

什么是混淆

把代码中原来有具体含义的包名、类名、变量名、方法名等名称全部替换成无意义的字母a/b/c…

为什么要混淆

由于Android是基于Java语言的,而Java属于高层抽象语言,易于反编译,其编译后的程序包中包含了大量的源代码变量、方法名、数据结构等近乎源码的信息,等同于将源码拱手送人。因此为了保护自己的劳动成果以及项目私密问题,我们需要给自己的项目加上混淆。

混淆会出现什么问题

不难理解,由于混淆后,各种变量、方法、类等信息变成了无意义的字母a/b/c,所以会出现ClassNotFoundException的错误,为了避免出现这样的错误,我们需要添加一系列的规则,来标注出我们不希望混淆的地方。

常见的保持相关元素不参与混淆的几种指令

命令 作用
-keep 防止类和成员被移除和被重命名
-keepclassmembers 防止成员被移除和被重命名
-keepnames 防止类和成员被重命名
-keepclassmembernames 防止成员被重命名
-keepclasseswithmembers 防止拥有该成员的类和成员被移除或重命名
-keepclasseswithmembernames 防止拥有该成员的类和成员被重命名

没有规则

Android代码混淆_第1张图片
none.png

默认值,如果你没有指定任何类型的keep指令,那么它会压缩(删除未使用的代码)并对类和类成员进行模糊处理(即重命名)

-keep

Android代码混淆_第2张图片
keep.png

-keep为不压缩、不混淆。

-keepclassmembers

Android代码混淆_第3张图片
keepclassmembers.png

使用这个规则,如果一个类未被使用,则会被删除。如果一个类被使用了,则会重命名这个的类的名字,它所有的成员都还在,并且还是原来的名字。

-keepnames

Android代码混淆_第4张图片
keepnames.png

允许类和成员压缩,但不能混淆。也就是说,任何未使用的代码都将被删除,但保留下来的代码将保留其原始名称。

-keepclassmembernames

Android代码混淆_第5张图片
keepclassmembernames.png

删除未使用的类和成员变量,混淆类名,保留成员的原始名称。

-keepclasseswithmembers

与-keep相同,不同之处在于它仅适用于具有类规范中所有成员的类。

-keepclasseswithmembernames

此规则与-keepnames相同。不同的是,它仅适用于具有类规范中所有成员的类。

更多详细的请到官网

保持元素不参与混淆的规则

[保持命令] [类] {
    [成员]
}

[类]表示类相关的限定条件,它将最终定位到某些符合该限定条件的类。它的内容可以使用:

  • 具体的类
  • 访问修饰符(public、protected、private)
  • 通配符*,匹配任意长度字符,但不含包名分隔符.
  • 通配符**,匹配任意长度字符,并且包含包名分隔符.
  • extends,即可以指定类的基类
  • implement,匹配实现了某接口的类
  • $,内部类

[成员]代表类成员相关的限定条件,它将最终定位到某些符合该限定条件的类成员。它的内容可以使用:

  • 匹配所有构造器
  • 匹配所有方法
  • 通配符*,匹配任意长度字符,但不含包名分隔符.
  • 通配符**,匹配任意长度字符,并且包含包名分隔符.
  • 通配符***,匹配任意参数类型
  • ...,匹配任意长度的任意类型参数。比如void test(...)就能匹配任意void test(String a)或者是void test(int a, int b)这些方法
  • 访问修饰符(public、protected、private)
    例如,需要将com.demo.test包下所有继承Activity的public类及其构造函数都保持住,可以这么写:
-keep public class com.webi.mixdemo.*** extends Android.app.Avtivty{
    
}

你可能感兴趣的:(Android代码混淆)