1、ProGuard的常用语法
-libraryjars class_path 应用的依赖包,如android-support-v4
-keep [,modifier,...] class_specification 不混淆某些类
-keepclassmembers [,modifier,...] class_specification 不混淆类的成员
-keepclasseswithmembers [,modifier,...] class_specification 不混淆类及其成员
-keepnames class_specification 不混淆类及其成员名
-keepclassmembernames class_specification 不混淆类的成员名
-keepclasseswithmembernames class_specification 不混淆类及其成员名
-assumenosideeffects class_specification 假设调用不产生任何影响,在proguard代码优化时会将该调用remove掉。如system.out.println和Log.v等等
-dontwarn [class_filter] 不提示warnning
关于proguard更多语法可见:http://proguard.sourceforge.net/index.html#manual/usage.html
2、标准proguard.cfg文件内容
参考android标准,修改如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
#
see
http
:
/
/sourceforge
.net
/tracker
/
?func
=detail
&aid
=2787465
&group
_id
=54750
&atid
=474707
-optimizations
!code
/simplification
/arithmetic
-optimizations
!code
/simplification
/cast
-allowaccessmodification
#
To
prevent
name
conflict
in
incremental
obfuscation
.
-useuniqueclassmembernames
#
dex
does
not
like
code
run
through
proguard
optimize
and
preverify
steps
.
-dontoptimize
-dontpreverify
#
Don
't obfuscate. We only need dead code striping.
# -dontobfuscate
# Add this flag in your package's
own
configuration
if
it
's needed.
#-flattenpackagehierarchy
# Some classes in the libraries extend package private classes to chare common functionality
# that isn't
explicitly
part
of
the
API
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
#
For
enumeration
classes
,
see
http
:
/
/proguard
.sourceforge
.net
/manual
/examples
.html
#enumerations
-keepclassmembers
enum
*
{
public
static
*
*
[
]
values
(
)
;
public
static
*
*
valueOf
(java
.lang
.String
)
;
}
#
For
native
methods
,
see
http
:
/
/proguard
.sourceforge
.net
/manual
/examples
.html
#native
-keepclasseswithmembernames
class
*
{
native
<methods>
;
}
# class$ methods are inserted by some compilers to implement .class construct,
# see http://proguard.sourceforge.net/manual/examples.html#library
-keepclassmembernames class * {
java.lang.Class class$(java.lang.String);
java.lang.Class class$(java.lang.String, boolean);
}
# Keep classes and methods that have the guava @VisibleForTesting annotation
-keep @com.google.common.annotations.VisibleForTesting class *
-keepclassmembers class * {
@com.google.common.annotations.VisibleForTesting *;
}
# Keep serializable classes and necessary members for serializable classes
# Copied from the ProGuard manual at http://proguard.sourceforge.net.
-keepnames class * implements java.io.Serializable
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient
<fields>
;
private
void
writeObject
(java
.io
.ObjectOutputStream
)
;
private
void
readObject
(java
.io
.ObjectInputStream
)
;
java
.lang
.Object
writeReplace
(
)
;
java
.lang
.Object
readResolve
(
)
;
}
#
Please
specify
classes
to
be
kept
explicitly
in
your
package
's configuration.
# -keep class * extends android.app.Activity
# -keep class * extends android.view.View
# -keep class * extends android.app.Service
# -keep class * extends android.content.BroadcastReceiver
# -keep class * extends android.content.ContentProvider
# -keep class * extends android.preference.Preference
# -keep class * extends android.app.BackupAgent
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
# The support library contains references to newer platform versions.
# Don't
warn
about
those
in
case
this
app
is
linking
against
an
older
#
platform
version
.
We
know
about
them
,
and
they
are
safe
.
#
See
proguard
-android
.txt
in
the
SDK
package
.
-dontwarn
android
.support
.
*
*
|
源文件见<android_root>/build/core/proguard.flags , 将14行 -dontobfuscate解除注释。
3、常用proguard.cfg代码段
不混淆某类的构造方法,需指定构造函数的参数类型,如JSONObject
1
2
3
|
-
keepclassmembers
class
cn
.
trinea
.
android
.
common
.
service
.
impl
.
ImageCache
{
public
<init>
(
int
)
;
}
|
不混淆某个包所有类或某个类class、某个接口interface, 不混淆指定类则把**换成类名
1
|
-
keep
class
cn
.
trinea
.
android
.
common
.
*
*
{
*
;
}
|
不混淆指某个方法,*可换成指定的方法或类名
1
2
3
|
-
keepclassmembers
class
cn
.
trinea
.
android
.
common
.
service
.
impl
.
ImageCache
{
public
boolean
get
(
java
.
lang
.
String
,
android
.
view
.
View
)
;
}
|
不混淆Parcelable的子类,防止android.os.BadParcelableException
1
2
3
|
-
keep
class
*
implements
android
.
os
.
Parcelable
{
public
static
final
android
.
os
.
Parcelable
$
Creator
*
;
}
|
添加android-support-v4.jar依赖包
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
.
*
*
{
*
;
}
|
4、proguard与log level结合解决debug模式Log问题
常见的Android debug日志的打法是定义一个静态变量DEBUG_STATUS,如果为true,则打印log,否则不打印。对于release模式该变量为false,debug模式变量为true。这里介绍一个更好的方法,不用担心正式发布时一不小心错改了该变量。
proguard的作用就是在release模式压缩、优化、混淆代码,其中的压缩和优化就包括去除不必要的代码,我们可以利用这一特性解决debug日志的问题,在proguard.cfg中添加
1
2
3
4
|
-
assumenosideeffects
class
android
.
util
.
Log
{
public
static
*
*
*
d
(
.
.
.
)
;
public
static
*
*
*
v
(
.
.
.
)
;
}
|
表示Log.d和Log.v代码无副作用,在proguard时会被从源码中remove掉,这样release模式(正式发布)就不会打印日志了,而debug模式(平常调试)照常打印,不用修改一点代码大赞吧,嘿嘿*_^