Android中的Proguard使用

介绍

之前介绍了如何使用命令行将Jar包根据配置文件进行ProGuard,以及ProGuard的过程,会遇到的问题等。接下来会介绍常用的ProGuard如何配置参数。不常用的可以在官网中查询如何使用。

java -jar proguard.jar @myconfig.pro

Filter

每一个类、属性、方法都会有一个全名,例如java.lang.String。而我们也可以通过正则表达式来过滤我们所需要的名称。

  • ?:在class中匹配任意的单个字符
    例如:mypackage.Test?可以匹配mypackage.Test1,mypackage.Test2,但是不能匹配mypackage.Test12
  • *:匹配任意class名称中的一部分
    例如:mypackage.*Test*可以匹配mypackage.Test,也可以匹配mypackage.YouTestApplication,但是不能匹配mypackage.subpackage.MyTest
  • **:可以匹配class名称中的任意一部分,可以包括任何数字或者包分隔符。
    例如:**.Test可以匹配除了根目录下所有包名下的Test类。mypackage.**则可以匹配所有在mypackage和它子目录的所有类

而Fields和Methods与Java中类似。除了Method的参数中不需要包含它的名字,就和Javap中一样。而匹配规则如下:

  • <init>:匹配任意构造函数
    -<fields>:匹配任意属性
    -<methods>:匹配任意函数
    -*:匹配任意属性或者函数

Input / Output Options

  • @filename
    这种方式,是-include filename的缩写,该选项的作用是递归读取所给文件中的属性

  • -basedirectory directoryPath
    指定配置文件的目录

  • -injars class_path
    指定输入Jar包的路径,可以指定多个路径,而输入的Entity可以被过滤

  • -outjars class_path
    指定输出Jar包路径,同上而输出的Entity可以被过滤

  • libraryjars class_path
    指定要被处理的Jar包。这些文件不会被打包到output jar包中。指定的Library应该至少包含一个Class文件被Application Class文件中使用extended继承了。

  • -skipnonpubliclibraryclasses
    当读取library的时候,跳过non-public的类,以提升处理速度并且减少ProGuard内存占用。默认ProGuard会读取public以及non-public的类。然而,non-public的类通常没有关联的。可以忽略他们,提升ProGuard速度,而且也不会影响output。但是有一些lib,例如JSE run-time,包含了non-public的类,但是它还可以被public的library继承。所以你不能使用这个option。如果因为这个option无法找到那个class的话 ,ProGuard会打印出来Warning的。

  • -dontskipnonpubliclibraryclasses
    从4.5版本开始,默认就指定了该属性。该属性制定了不要忽略non-public的类

  • -dontskipnonpubliclibraryclassmembers
    指定不要忽略package visible的类成员(Field以及Method)。默认的,ProGuard在解析classes会跳过这些类成员,因为程序通常不会引用它们。有些情况下,程序的包和Library的包相同,从而可以引用包可见的类成员。在这种情况下,实际读取类成员是有用的,以确保处理后的代码保持一致。

  • keepdirectories directory_filter
    指定输出路径中需要Keep的目录。默认情况下,目录的Entries会被移除掉,用来减少Jar包的大小。但是有可能程序会有MyClass.class.getResource("")这种代码出现,如果没有指定一个Directory Filter的话,那么所有的目录都会被Keep住。如果有Filter的话,则会Keep匹配目录。

Keep Options

  • -keep:
    Keep住所有继承自Activity、Application的类
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider

Keep住所有继承自View类中的public构造函数以及所有以public void set开始的函数。

-keep public class * extends android.view.View {
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
    public void set*(...);
}
  • -keepclassmembers
    Keep住类中的成员。
-keepclassmembers class * implements java.io.Serializable {
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}
-keepclassmembers class * implements android.os.Parcelable {
    static android.os.Parcelable$Creator CREATOR;
}
-keepclassmembers class **.R$* {
    public static <fields>;
}
  • -keepclasseswithmembers
    Keep住能匹配到规则的类。如下,会Keep住所有构造函数带有Context、AttributeSet的类。
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}
  • -keepclassmembernames
    Keep住类成员。如果它们没有在Shrink阶段被移除的话
-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinPool {
    long eventCount;
    int  workerCounts;
    int  runControl;
    scala.concurrent.forkjoin.ForkJoinPool$WaitQueueNode syncStack;
    scala.concurrent.forkjoin.ForkJoinPool$WaitQueueNode spareStack;
}
  • -keepclasseswithmembernames
    根据类成员名称来Keep住类。如下,如果有Native函数的类全部都会被Keep住
-keepclasseswithmembernames class * {
    native <methods>;
}

参考资料

ProGuard的使用

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 137,268评论 19赞 139
  • 混淆(Proguard)用法 最近项目中遇到一些混淆相关的问题,由于之前对proguard了解不多,所以每次都是面...
    于晓飞93阅读 57,269评论 38赞 230
  • 说明:本文参考(翻译)自Android SDK根目录下的proguard目录下的说明文档,是其中的一篇。,文中除了...
    一件小毛衣阅读 86,580评论 9赞 86
  • 混淆规则 因为Android是使用Java开发的,所以开发者可以使用ProGuard对代码进行混淆。SDK已经集成...
    CarlosLynn阅读 1,741评论 0赞 0
  • 我第一次来到这个地方,总觉得应该留下些什么,好做开始...... 你知道我现在在纠结什么?是深沉的娓娓道来,还是逗...
    小婵哥阅读 238评论 1赞 2

友情链接更多精彩内容