ProGuard的作用、使用及bug分析

本文主要ProGuard的作用、使用及bug分析。
1、ProGuard作用
ProGuard通过删除无用代码,将代码中类名、方法名、属性名用晦涩难懂的名称重命名从而达到代码混淆、压缩和优化的功能,跟JavaScript的混淆压缩类似。
压缩和优化使得编译后apk包更小。
混淆可以保证代码在被反编译后读懂的难度很大,防止逆向工程。这点也是我们在应用发布前需要ProGuard的一大原因。

2、ProGuard的使用
(1). 系统应用:
在项目根目录下的Android.mk文件中添加

XHTML


1

2


LOCAL_PROGUARD_FLAG_FILES := proguard.cfg

LOCAL_PROGUARD_ENABLED := full

这样应用不需要单独设置proguard配置文件,在系统编译时会采用系统统一的proguard.cfg对该应用进行proguard,系统proguard.cfg位于系统根目录\build\core内。

(2). 非系统应用:
a. 打开ProGuard开关
在项目根目录下的project.properties文件中配置proguard,添加如下代码:

XHTML


1


proguard.config=proguard.cfg

这样在release模式下打包apk之前,proguard会以proguard.cfg为规则处理应用字节码。关于release模式下面第c部分会进行介绍

b. 编写自己的proguard config文件
默认会对所有代码混淆,如果需要部分混淆,可以自己修改proguard.cfg文件
关于proguard config的语法及标准配置可见:Proguard语法及常用proguard.cfg代码段

注意下列类不能进行混淆:
(1)、反射用到的类
(2)、在AndroidManifest中配置的类(Activity、Service等的子类及Framework类默认不会进行混淆)
(3)、Jni中调用的类

c. 运行ProGuard及其生成的文件介绍
在以release模式下打包apk时会自动运行ProGuard,这里的release模式指的是通过ant release命令或eclipse project->android tools->export signed(unsigned) application package生成apk。在debug模式下为了更快调试并不会调用proguard。

如果是ant命令打包apk,proguard信息文件会保存于<project_root>/bin/proguard文件夹内;如果用eclipse export命令打包,会在<project_root>/proguard文件夹内。其中包含以下文件:

mapping.txt表示混淆前后代码的对照表,这个文件非常重要。如果你的代码混淆后会产生bug的话,log提示中是混淆后的代码,希望定位到源代码的话就可以根据mapping.txt反推。
dump.txt描述apk内所有class文件的内部结构
seeds.txt列出了没有被混淆的类和成员
usage.txt列出了源代码中被删除在apk中不存在的代码

下图为mapping.txt部分内容,以及混淆前后的代码对比:


从中可以看出混淆后代码大多abcdefg..

注意:养成保存mapping.txt的习惯。ProGuard会在每次运行时覆盖原来的文件,所以每次发布请保存mapping.txt,方便该版本出现问题时调出日志进行排查。mapping.txt可以根据版本号或是发布时间命名来保存或是放进代码版本控制中。

d. ProGuard是否成功检查

可以通过反编译Apk检查proguard是否成功,如果成功代码会类似上面的截图,大部分类名及成员名都是形如a.b.c…。关于反编译请参考:Android Apk 反编译

3、ProGuard混淆后bug分析
(1) 代码本身bug
混淆后bug提示信息中代码都是混淆后代码,类a. b. c…,如果需要排查,就得根据mapping.txt文件去反推实际代码中对应的代码段从而解决问题
PS:混淆后代码中的$表示匿名内部类,根据代码中顺序依次为OutClassName$1, OutClassName$2

(2) 因混淆而产生的bug
应用可能会因为ProGuard混淆了不该混淆的代码而产生一些bug,其中最常见的就是ClassNotFoundException,还有BadParcelableException等
对于ClassNotFoundException,根据mapping.txt文件反推找到某个类,然后在proguard.cfg中不进行混淆即可

Java


1


-keep class packagename.classname { *; }

对于android.os.BadParcelableException: Parcelable protocol requires a Parcelable.Creator object called CREATOR,proguard.cfg中添加

Java


1

2

3


-keep class * implements android.os.Parcelable {

public static final android.os.Parcelable$Creator *;

}

对于android.support.v4 can’t find superclass or interface,can’t find referenced method,proguard.cfg中添加

Java


1

2

3

4


-libraryjars libs/android-support-v4.jar

-dontwarn android.support.v4.**

-keep class android.support.v4.** { *; }

-keep interface android.support.v4.app.** { *; }

proguard混淆后其他问题可见:http://proguard.sourceforge.net/index.html#manual/troubleshooting.html

时间: 2024-09-10 06:19:56

ProGuard的作用、使用及bug分析的相关文章

MySQL · 答疑解惑 · 外键删除bug分析

背景 你是否曾为Error on rename of './test/#sql-78fd_780371' to './test/t2' (errno: 150)这样的错误而不解,如stackoverflow上的这个问题? 下面我们来复现下: drop table t2; drop table t1; create table t1(c1 int primary key, c2 int); create table t2(c1 int primary key, c2 int , constrain

软件测试中的BUG分析定位概述(QA如何分析定位BUG)

你是否遇到这样的场景? QA发现问题后找到DEV说: 不好了,你的程序出问题了! DEV(追查半小时之后): 唉,是你们测试环境配置的问题 唉,是你们数据不一致 唉,是你们**程序版本不对 唉,是**产品线的问题 当时的日志呢? 当时cpu有异常么? 可以复现么? 这里就应该是这样啊! 你是否期待这样的场景? QA发现问题后,经分析判断,胸有成竹的找到DEV说: 你的程序出bug了,初步断定是XX类的XX判断分支有问题,应该把某某的判断一改就好了!--==定位精准== 你的程序出bug了,过去某

[WPF]RadioButton在Group的Header区部分不响应鼠标选择的bug分析

昨晚看到南柯之石的WPF BUG之四:点击RadioButton的空白没有反应,就做了简单的验证,之后发表了一些分析和看法, 但是那个分析不够准确和充分,会误导别人的想法.在此表示歉意.这里我会从头做分析. 由于南柯之石已经描述过bug,这里只是简单说一下:就是在GroupBox的Header上放一个RadioButton,此时鼠标点击RadioButton的某些空白区域没有反应. 下面言归正传,开始对这个bug的探索: 首先这里给出出现bug的xaml片段(这个从南柯之石的blog转帖过来的,

SQLServer · BUG分析 · Agent 链接泄露分析

背景 SQLServer Agent作为Windows服务提供给用户定期执行管理任务,这些任务被称为Job:考虑应用镜像的场景如何解决Job同步问题,AWS RDS的做法是不予理会,由用户维护Job,假如发生切换用户需要在新的Principal端创建Job:另一种做法是镜像端保持同步Job,切换后尽量让用户无感知不需要多余维护动作,但这种做法在某些情况会遇到非常严重的问题--内存耗尽. 问题排查分析 第一次分析 问题发生时实例的ERRORLOG出现: Error: 701, Severity:

MySQL · 捉虫状态 · bug分析两例

BUG 1 IN查询结果不对 背景 在mysql5.6.16版本下,构建如下测试用例 CREATE TABLE `a` ( `c1` varchar(512) NOT NULL DEFAULT '' ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `a` VALUES ('i-28s18atup'),('i-2850jdoa2'),('i-2872jv9o8'),('i-289z59set'),('i-2812c0mz1'),(''),('')

mysql数据库UPDATE语句一个bug分析

这个我认为的bug,反馈给MySQL官方,但是MySQL官方认为这并不是一个bug,并给出了解释,我认为这个解释是合理的,但是不可避免的是这条语句实在太危险了. 问题描述 示例表结构与表数据: # 表结构 mysql> show create table t; +-------+--------------------------------------------------------------------------------------------------------------

css IE6/7 padding-bottom Bug分析

e8/9(标准模式) and firefox/safari/chrome/opera ie6/7 and ie8/9(怪异模式) 外层div加了上下padding 15px,可是在ie6/7 and ie8/9(怪异模式)下padding却翻倍了. <!doctype html> <html> <head>  <meta charset="utf-8">  <title>ie6/7 double padding-bottom

shell脚本中case条件控制语句的一个bug分析_linux shell

在shell脚本中,发现case语句的一个问题.就是指定小写字母[a-z]和大写字母[A-Z]的这种方法不管用了. 出现如下情况: 复制代码 代码如下: [root@station1 ~]# cat case.sh#!/bin/bashwhile :doecho -n "input a letter: "read varcase "$var" in  [a-z]) echo "Lowercase letter";;  [A-Z]) echo &q

CSS 3 transform 属性的 BUG分析介绍

最近在弄一个功能,需要通过弹窗来显示内容,取舍并尝试之后选择利用 CSS 3 transform 属性的 translate() 参数来实现弹窗的居中定位.   鼓捣了半天,测试 Chrome 完全正常,Edge 也正常,恩,到这里我觉得自己已经看到结局了,万万没想到,打开 IE 11 之后直接气的吐血!设置的 transform 属性竟然完全无效,说好的 IE 9 及以上就可以兼容的呢?怎么和想象中的不一样呀!   之前尝试各种让元素水平加垂直居中的方法,都各种因为什么表格嵌套啊,兼容性啊,适