在聊proguard使用之前,先说说proguard到底是什么东东,我主要做android开发,平时一般都听过android混淆打包的说法,直观的感觉就是把写好的java代码,通过一种编码方式给混淆了,让别人不容易看出代码逻辑以及java类之间的关系。其实,殊不知,这种混淆打包所依仗的就是这里要讲的progurad工具。

progurad工具实际上有四个功能。

压缩(Shrink):检测并移除代码中无用的类、字段、方法和特性(Attribute)。优化(Optimize):对字节码进行优化,移除无用的指令。混淆(Obfuscate):使用a,b,c,d这样简短而无意义的名称,对类、字段和方法进行重命名。预检(Preveirfy):在Java平台上对处理后的代码进行预检,确保加载的class文件是可执行的。

但是在android混淆打包中,我们实际上只需要使用Obfusacate这个混淆功能。

我们是通过配置命令的方式来使用proguard的,而命令又需要一些参数什么的,这个就涉及到通配符的问题,这里就从命令、通配符以及proguard不能混淆三个部分来对proguard进行总结。

1、proguard命令

根据我的个人经验,proguard使用最多的命令就是keep以及dontwarn这两个命令一个,一个表示保留对应的类方法属性等不要混淆,另一个就是表示不对指定的类、包中的不完整的引用发出警告。关于proguard的命令真的很多,遇到不懂得可以到ProGuard 最全混淆规则说明这篇文章中去查找,或者查看proguard manual

我们知道android中混淆打包需要进行配置

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

这里有一个proguard-android.txt是基础配置,还有一个proguard-rules.pro这个文件中开发这可以添加自己的一些配置。我们就以proguard-android.txt文件中的配置来简单说说proguard命令吧。

-dontusemixedcaseclassnames      #混淆时不生成大小写混合的类名,windows系统不能识别大小写-dontskipnonpubliclibraryclasses #不忽略指定jars中的非public calsses-verbose          #混淆过程中打印详细信息,如果异常终止则打印整个堆栈信息-dontoptimize     #关闭优化-dontpreverify    #关闭预验证,加快编译速度-keepattributes *Annotation* #指定要保留的任何可选属性,可以指定多个,用逗号分隔符分割-keep public class com.google.vending.licensing.ILicensingService   #指定对象不被混淆
-keep public class com.android.vending.licensing.ILicensingService#指定保留的类和类成员,这里是指保留带native方法的类不被混淆
-keepclasseswithmembernames class * { native <methods>;
}#指定需要保留的类成员:变量或者方法,这里保留自定义控件的set/get方法不被混淆
-keepclassmembers public class * extends android.view.View {void set*(***);*** get*();
}
-keepclassmembers class * extends android.app.Activity {public void *(android.view.View);
}
-keepclassmembers enum * {public static **[] values();public static ** valueOf(java.lang.String);
}-keepclassmembers class * implements android.os.Parcelable {public static final android.os.Parcelable$Creator CREATOR;
}
-keepclassmembers class **.R$* {public static <fields>;
}#不对指定的类、包中的不完整的引用发出警告
-dontwarn android.support.**#指定对象不被混淆
-keep class android.support.annotation.Keep
-keep @android.support.annotation.Keep class * {*;}#指定保留的类和类成员,这里指带Keep annotation的类不被混淆
-keepclasseswithmembers class * {@android.support.annotation.Keep <methods>;
}
-keepclasseswithmembers class * {@android.support.annotation.Keep <fields>;
}
-keepclasseswithmembers class * {@android.support.annotation.Keep <init>(...);
}

基础配置已经把常用的proguard命令都用上了,代码中也给出了解释,还有不懂得,请查看上面提到的两篇文章。

2、proguard的关键字和通配符

肯定有同学看了上面的配置后还是有疑惑,proguard命令知道了,那么第一小节代码中的*、…这些符号是啥啊,这些就是这一小节要讲的通配符了。

我们要指定混淆规则,但是项目中的类啊,方法什么的太多了,我们不能一个个去指定,那么通配符便大有用武之地了,通配符的作用便是通过符号统一指定一种类型的类、方法以及属性等的特殊符号。

那么关键字是什么呢,这个比较简单,就是配置代码中的class、interface、enum、extends、implements等字符。

class 关键字表示任何接口类、抽象类和普通类; interface 关键字表示只能是接口类; enum 关键字表示只能是枚举类。如果在 interface 和 enum 关键字前面加上感叹号(“ ! ”)分别表示不是接口类的类和不是枚举类的类,而 class 关键字前面不能加感叹号。

extends表示存在继承关系,而implements表示存在实现关系。

下面来分类说说通配符,proguard的“?”以及“*”应该是可以通用的,可以分别表示一个字符和n个字符(不含”.”)。但是对于类,方法、属性、以及参数、返回类型、参数类型等的通配符还是有一定差异的,下面直接给出作为参考。

类名

1) ? :问好代表一个任意字符,但不能是句号(“ . ”,因为句号是包名分隔符);
2) * :单个星号代表任意个任意字符,但不能代表句号”.”
3) ** :两个星号代表任意个任意字符,且能代表句号

成员变量

1)可以通过变量类型 fieldtype 和变量名 fieldname 来精确指定
2)可以通过 表示类中的任何成员变量
3)星号(“ * ”)可以匹配类中的任何成员变量和函数

成员函数

1)可以通过返回类型 returntype 、方法名 methodname 和参数类型 argumenttype 来唯一限定,
2) 可以通过 来表示类中的任何成员函数,
3)星号(“ * ”)可以匹配类中的任何成员函数

构造函数

1)可以用 加上构造函数的参数来指定。

成员函数名、成员变量名

1)问号(“ ? ”)可以匹配一个任意字符
2)星号(“ * ”)可以匹配任意多个任意字符

成员变量类型、成员函数返回类型以及参数、构造函数参数类型

1) % :匹配任何原始类型,如 boolean 、 int 等,但不包括 void ;

2) ? :匹配一个任意字符,不包括句号;

3) * :匹配任意个任意字符,不包括句号;

4) ** :匹配任意个任意字符,包括句号;

5) * :匹配任意类型,包括原始类型和非原始类型,数组类型和非数组类型;

6) … :匹配任何数目个任何类型的参数。

另外还需要说明的是,在类名前、类中成员变量和成员函数名前,可以加上访问限定符(如 public 、 private 、 protected 等,修饰类、成员变量和成员函数的访问限定符各不相同),如果加上了访问限定符后,就表示要匹配的类、成员变量或成员函数的定义中必须包含这些限定符。

3、android中不能混淆的代码

proguard混淆是把混淆对象的名字进行修改,而有些对象的名字不能被修改,否则会报错,比如Activity类,修改后AndroidManifest中就找不到对应的Activityl了肯定要报错,还有反射也是。那么这里便总结下android开发中不能被混淆的代码

1) Android系统组件

即在AndroidManifest文件中注册的组件,如Activity,Service,BroadcastReceiver,ContentProvider,Application等。这些组件通过字符串的形式告知系统,当被调用的时候,如果这些类名被改变了,那么系统就会找不到它们。所以一般组件不进行混淆。

2)Resource文件的使用

例如各种资源的名字在xml已经固定使用,如果混淆也将找不到。所以一般R文件不混淆。

3)序列化的类

包括Parcelable和Serializable。如果混淆了可能UID等会错误,而且在反序列化的时候会找不到对应的名字。

4)自定义控件

如果自定义控件在xml中使用了,那么也不能混淆,否则找不到,当然如果在代码中用的话应该没问题。

5)本地方法

不能修改本地方法名,否则和so文件对应的方法就无法找到了。

6.枚举

系统需要处理枚举的固定方法。

7)用到反射的地方

因为反射需要通过名字去找变量和方法名,所以混淆后可能找不到。例如实际情况中的接口返回数据对应的实体类等等。

8)ILicensingService系列

ILicensingService系列(好像是aidl用的)和BackupAgentHelper备份相关的,不能进行混淆,不过这个东西一般没人用,所以不必在意。

9)annotations 注释

一般注释混淆其实可以混淆,但是混淆常会和反射相关联,所以还是不要混淆的好。

10)android.preference.Preference

此Preference可不是SharedPrefrences(但是有点关联),这个Preference也是一个组件,所以不能混淆。

11)第三方包一般不混淆

首先,第三方包没必要混淆,既然是第三方的,那么一般都是公开的,也就没有必要保护。其次,第三方包可能自己已经混淆过了,不用我们动手了。最后,第三方包里面可能用到了上述的这些不能混淆的点,如果我们不了解它,擅自去混淆,可能导致不能正常运行的结果。

12)WebView中Java和Javascript互调的方法不能混淆

因为它们都是通过名字去互相调用,如果名字变了就会找不到对应的方法。

13)某些内部类的使用和泛型的使用需要避免混淆

到这里proguard知识,我想总结的就算是总结完了,可能看了这些都不能立即写出很好的proguard配置来,但是了解本博文知识点后会对怎么配置成竹在胸,也能知道什么对象是不能混淆的。关于proguard的配置,最好的还是在实际开发中多尝试,找感觉。

4、参考文献

本文的内容很多都来自于其它博客,都是稍作修改,感谢那些童鞋们的辛苦付出,把参考文献列在这里吧,也方便自己查看。

1、ProGuard 最全混淆规则说明

2、Android ProGuard混淆基本语法(和通用配置)

3、Android中混淆技术总结

4、ProGuard代码混淆技术详解

5、Android Studio(十一):代码混淆及打包apk

6、Android混淆打包那些事儿

关于proguard的使用总结相关推荐

  1. android类名方法名不混淆,android – 如何告诉Proguard混淆类名

    我想用proguard来混淆类名.我在Proguard.cfg中有这一行 -keepclasseswithmembers class * { public static ; } -keepnames ...

  2. 关于ProGuard的学习了解(从别处转来)

    from:http://www.cnitblog.com/zouzheng/archive/2011/01/12/72639.html 在Android项目中用到JNI,当用了proguard后,发现 ...

  3. Android项目:proguard混淆之常见开源项目混淆配置

    1.Gson混淆 ## ---------------------------------- ## ########## Gson混淆 ########## ## ------------------ ...

  4. ProGuard的返回错误代码1。异常的解决方法

    引用:http://wangwei121004-163-com.iteye.com/blog/1206595 ProGuard的返回错误代码1.See控制台 情况1: Proguard的返回错误代码1 ...

  5. [转载]关于Android ProGuard混淆学习记录

    转自:http://www.cnitblog.com/zouzheng/archive/2011/01/12/72630.aspx 前段时间把Android的工程用Ant Build搞定后,现在需要把 ...

  6. Android 开发应该掌握的 Proguard 技巧

    本文由玉刚说写作平台提供写作赞助 原作者:Sen 版权声明:本文版权归微信公众号玉刚说所有,未经许可,不得以任何形式转载 Proguard介绍 Proguard被人们熟知的是它的混淆功能,根据Prog ...

  7. Android ProGuard使用要点

    1.基本的的使用可以很容易百度到, 但是当你使用了android-support-v4或者android-support-v7或者android-support-v11包之后,你发现导出的时候, 警告 ...

  8. proguard java 教程,[Gradle中文教程系列]-跟我学Gradle-使用proguard混淆你的spring boot应用...

    使用proguard混淆你的spring boot应用 Proguard介绍 安卓开发的同学想必对Proguard都是十分熟悉的,由于java的反编译实在是太容易,使用它可以对java源码进行混淆处理 ...

  9. Proguard returned with error code 1. See console

    满世界的bug. 微信支付,Windows的远程桌面. Android的 , Proguard returned with error code 1. See console解决办法" 真的 ...

  10. android proguard 第三方jar,Android Studio代码混淆-第三方jar混淆汇总(持续更新)

    前言 Android有非常多的优秀的第三方开源jar包,我们经常在我们的项目中使用了不少jar包,但是往往到了release的时候就忘了混淆第三方jar包了,会给我们开发带来不少麻烦,所有在这里汇总一 ...

最新文章

  1. 乾坤 微前端_微前端架构初探以及我的前端技术盘点
  2. 跟我一起写 Makefile(十)
  3. java update多个字段的值_SQL的update多个字段的写法
  4. c#写字板实现加粗功能_Windows 7中写字板和绘画中的新功能
  5. 【README1】动态规划之解题思路
  6. fastdfs-配合nginx-麻烦的
  7. 【tool】常见功能测试点
  8. java 综合练习_Java 之综合练习
  9. c语言程序设计 网上资源,超星尔雅C语言程序设计-资源包完整答案
  10. Flameshot——最好用的ubuntu截图工具
  11. matlab更改类型,matlab数据类型和转换
  12. SmartBi V9系统运维总结
  13. 逍遥安卓模拟器卡android,逍遥模拟器不流畅解决方法 逍遥安卓模拟器怎么设置不卡...
  14. 计算机内部可以用哪两种处理器封装类型,电脑CPU处理器封装形式大盘点
  15. 一篇文章教你正确解锁 代理ip 的使用方式,包含两个实战案例
  16. 华三交换机irf堆叠以及BFD检测配置
  17. [转载]如何在非443端口开https
  18. 二级学科 计算机科学技术,一级学科、二级学科,考研专业哪个包含了计算机考研方向...
  19. 使用OpenCV读取视频和视频的相似性度量
  20. 生物碱基c语言编程,新的CRISPR C-G DNA碱基编辑器

热门文章

  1. PHP代码审计的方法与步骤
  2. PyQt5 第六章 拖拽和绘画(三)
  3. 烧写Firmware-Mfg-emmc.lfp步骤
  4. 脚本监控windows的cpu 内存 磁盘 使用率
  5. 补充:字典与集合应用实例(p.113)
  6. linux pm,Kali Linux下配置PM3运行环境
  7. 解决笔记本电脑时不时传出咚咚咚的声音问题
  8. java fx fxml界面_使用 JavaFX 2.0 FXML 呈现企业应用程序的 UI
  9. 网络流入门——算法模板,习题和解析
  10. 2023跨年倒计时代码来了!