Android 开发应该掌握的 Proguard 技巧

Proguard介绍

Proguard被人们熟知的是它的混淆功能,根据Proguard帮助文档的描述,Proguard可以对Java class 文件进行shrink,optimize,obfuscate和preveirfy。obfuscate(混淆)只是其中之一。简要的介绍下这四个功能:

压缩(Shrink): 检测和删除没有使用的类,字段,方法和特性

优化(Optimize) : 分析和优化Java字节码

混淆(Obfuscate): 使用简短的无意义的名称,对类,字段和方法进行重命名

预检(Preveirfy): 用来对Java class进行预验证(预验证主要是针对JME开发来说的,Android中没有预验证过程,默认是关闭)

补充说明:根据proguard-android-optimize.txt对optimize的描述,在Android中使用该功能是有潜在风险的,并不能保证在所有版本的Dalvik虚拟机上正常运行,该选项默认是关闭的,如果开启,请做好全面的测试。在Android项目中,我们在相应module下的build.gradle文件中会看到

 buildTypes {
 release {
 minifyEnabled true
 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
 }
 }

其中 minifyEnabled 为true是开启Proguard的功能,false是关闭。

Proguard工作流程

Prouguard的工作流程如下图所示:

可以看出, Proguard工作流程是对输入的jars经过shrink->optimize->obfuscate->preveirfy依次处理,图中library jars是input jars运行所依赖的包,比如Java运行时的rt.jar,Android运行时android.jar,这些jars在上述处理过程中不会有任何改变,仅是作为输入jars的依赖。

大家可能会有一个疑问,Proguard是怎么知道哪些类,方法,成员变量等是无用的呢,这就要说到Entry Point(入口点),我们在配置文件(包括默认的proguard-android.txt)中写入的一系列-keep选项,都会作为Entry Point,Proguard把这些Entry Points作为搜索的入口,进行递归检索,以此来确定哪些部分未使用到。类似于hotspot虚拟机对可回收对象的判定,从GC Roots出发,进行可达性的判断,不可达的为可回收对象。Entry Points非常重要,Proguard的压缩,优化,混淆功能是以Entry Point作为依据的(预检不需要以此为依据)。

在压缩过程中,Proguard从Entry Points出发,递归检索,删除那些没有使用到的类和类的成员,在接下来的优化过程中,那些非Entry Points的类和方法会被设置成private,static或final,没有使用到的参数会被移除,有些方法可能会被标记为内联的,在混淆过程中,会对非EntryPoint的类和类的成员进行重命名,也就是用其它无意义的名称代替。我们在配置文件中用-keep保留的部分属于Entry Point,所以不会被重命名。

Proguard配置文件的依据

说起重命名,为什么需要保留一些类和类的成员(方法和变量)不被重命名呢 ? 原因是Proguard对class文件经过一系列处理后,能保证功能上和原来是一样的,但有些情况它却不能良好的处理,比如我们代码中有些功能依赖于它们原来的名字,如反射功能,native调用(函数签名)等,如果换成其它名字&

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值