最近在Eclipse平台上使用ProGuard进行了Android 安装包的混淆,由于时间紧凑,简单在网上搜集了一些属性,完成了工作任务。进来,又进行了进一步的研究。

1.启用Proguard

在项目的project.properties中有:

# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

那么我们怎么选择是使用proguard-android.txt还是proguard-project.txt?打开这两个文件后,发现他们都指向了proguard-android.txt,为了便于修改copy一份到当前项目的目录下,修改project.properties文件,设置proguard.config=proguard-project.txt(这里将proguard-android.txt重命名为proguard-project.txt)

1.Eclipse常用Proguard命令

首先咱们参照proguard-android.txt原始文件,解读Proguard中用到的关键词

-dontusemixedcaseclassnames
Specifies not to generate mixed-case class names while obfuscating. By default, obfuscated class names can contain a mix of upper-case characters and lower-case characters. This creates perfectly acceptable and usable jars. Only if a jar is unpacked on a platform with a case-insensitive filing system (say, Windows), the unpacking tool may let similarly named class files overwrite each other. Code that self-destructs when it’s unpacked! Developers who really want to unpack their jars on Windows can use this option to switch off this behavior. Obfuscated jars will become slightly larger as a result. Only applicable when obfuscating.
大致意思:
混淆代码的时候,默认是大小写混合的。如果在一些不区分大小写的系统上(eg.windows)反编译APK就很有可能造成代码的相互重写,产生错误。
评论:惯例添加。
-dontskipnonpubliclibraryclasses
Specifies not to ignore non-public library classes. As of version 4.5, this is the default setting.
大致意思:
一定要混淆添加的jar包里面的非public类。
评论:添加无妨。
-verbose
Specifies to write out some more information during processing. If the program terminates with an exception, this option will print out the entire stack trace, instead of just the exception message.
大致意思:
Proguard混淆项目失败后,打印完成的错误信息。
评论:这个还是很有必要的,第一次使用Proguard应该会碰到不少问题。
-dontoptimize
Specifies not to optimize the input class files. By default, optimization is enabled; all methods are optimized at a bytecode level.
大致意思:
Proguard仅仅执行项目的混淆不执行对代码的优化。
评论:惯例添加。
-dontpreverify
Specifies not to preverify the processed class files. By default, class files are preverified if they are targeted at Java Micro Edition or at Java 6 or higher. For Java Micro Edition, preverification is required, so you will need to run an external preverifier on the processed code if you specify this option. For Java 6, preverification is optional, but as of Java 7, it is required. Only when eventually targeting Android, it is not necessary, so you can then switch it off to reduce the processing time a bit.
大致意思:
为了提高Proguard执行的效率,不再进行Android中不需要的preverify;
评论:没有必要做无用功。
-keepattributes *Annotation*
-keepattributes [attribute_filter]
Specifies any optional attributes to be preserved. The attributes can be specified with one or more -keepattributes directives. The optional filter is a comma-separated list of attribute names that Java virtual machines and ProGuard support. Attribute names can contain ?, , and * wildcards, and they can be preceded by the ! negator. For example, you should at least keep the Exceptions, InnerClasses, and Signature attributes when processing a library. You should also keep theSourceFile and LineNumberTable attributes for producing useful obfuscated stack traces. Finally, you may want to keep annotations if your code depends on them. Only applicable when obfuscating.
大致意思:
指定可以保留的属性,这里面可以使用通配符。通配符具体解释见下文。
-keepattributes Annotation 指定保留Android中的动画特效
评论:惯例保留。
-keep public class com.google.vending.licensing.ILicensingService
作用:不对com.google.vending.licensing.ILicensingService类名称进行混淆
-keep public class com.android.vending.licensing.ILicensingService
作用:不对class com.android.vending.licensing.ILicensingService类名称进行混淆
下面讲述一下
Keep Options
-keep [,modifier,…] class_specification
Specifies classes and class members (fields and methods) to be preserved as entry points to your code. For example, in order to keep an application, you can specify the main class along with its main method. In order to process a library, you should specify all publicly accessible elements.
大体意思:
指定保留的类或者类成员,作为程序入口。如果作为一个libary Project应该指定所有向外暴露的,供外界调用的元素。
-keepclassmembers [,modifier,…] class_specification
Specifies class members to be preserved, if their classes are preserved as well. For example, you may want to keep all serialization fields and methods of classes that implement the Serializable interface.
大体意思:
指定要保留的类成员。这个东西在Serializable中经常用到。
-keepclasseswithmembers [,modifier,…] class_specification
Specifies classes and class members to be preserved, on the condition that all of the specified class members are present. For example, you may want to keep all applications that have a main method, without having to list them explicitly.
大体意思:
保留拥有所有这些成员的类。避免了直接罗列所有类名的麻烦。相当于一个通配吧!
-keepnames class_specification
Short for -keep,allowshrinking class_specification
Specifies classes and class members whose names are to be preserved, if they aren’t removed in the shrinking phase. For example, you may want to keep all class names of classes that implement the Serializable interface, so that the processed code remains compatible with any originally serialized classes. Classes that aren’t used at all can still be removed. Only applicable when obfuscating.
大体意思:
在Proguard完成项目压缩,删除没有使用的代码后,如果该类或类的成员没有被删除则进行保留。
评论:
显然所有的的保留都是为了代码的使用,没有使用的类或者成员当然没有存在的必要。尽量使用-keepnames而不是-keep。
-keepclassmembernames class_specification
Short for -keepclassmembers,allowshrinking class_specification
Specifies class members whose names are to be preserved, if they aren’t removed in the shrinking phase. For example, you may want to preserve the name of the synthetic class$ methods when processing a library compiled by JDK 1.2 or older, so obfuscators can detect it again when processing an application that uses the processed library (although ProGuard itself doesn’t need this). Only applicable when obfuscating.
大体意思:
在Proguard压缩代码后,指定需要保留的类成员。尽量使用-keepclassmembernames 而不是-keepclassmembers。
-keepclasseswithmembernames class_specification
Short for -keepclasseswithmembers,allowshrinking class_specification
Specifies classes and class members whose names are to be preserved, on the condition that all of the specified class members are present after the shrinking phase. For example, you may want to keep all native method names and the names of their classes, so that the processed code can still link with the native library code. Native methods that aren’t used at all can still be removed. If a class file is used, but none of its native methods are, its name will still be obfuscated. Only applicable when obfuscating.
大体意思:
在Proguard压缩代码后,指定需要保留的类和类成员。
评论:
尽量使用-keepclasseswithmembernames 而不是-keepclasseswithmembers。
-printseeds [filename]
Specifies to exhaustively list classes and class members matched by the various -keep options. The list is printed to the standard output or to the given file. The list can be useful to verify if the intended class members are really found, especially if you’re using wildcards. For example, you may want to list all theapplications or all the applets that you are keeping.
大体意思:
将所有的keep信息输出到[filename].
*-keepclasseswithmembernames class * {
native ;
}*
作用:Proguard压缩代码后,保留所有有native方法的类。如果项目中有NDK调用这个非常重要,如果自己没有调用,使用的一些第三方的东西也可能有调用。写上准没错。

*-keepclassmembers public class * extends android.view.View {
void set*(*);
* get*();
}*
作用:保留自定义View的get,set方法,用于展示Animation效果。
*-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}*
We want to keep methods in Activity that could be used in the XML attribute onClick
作用:为了让在xml中绑定的onClick事件仍然可以响应。
*-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}*
If your application, applet, servlet, library, etc., contains enumeration classes, you’ll have to preserve some special methods. Enumerations were introduced in Java 5. The java compiler translates enumerations into classes with a special structure. Notably, the classes contain implementations of some static methods that the run-time environment accesses by introspection (Isn’t that just grand? Introspection is the self-modifying code of a new generation). You have to specify these explicitly, to make sure they aren’t removed or obfuscated。
大体意思:
Java编辑器将枚举类转化为一个特殊的数据结构。其中,包含Java运行环境通过introspection 访问的一些静态方法。
结论:
代码中有枚举类,这个一定要有。没有用到枚举类,添加也无妨。
*-keepclassmembers class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator CREATOR;
}*
We’re also keeping the required static fields in Parcelable implementations, since they are accessed by introspection.
大体意思:
保留Parcelable的静态域,运行环境通过introspection访问他们。
结论:
如果代码中用到了Parcelable就添加上吧!

-keepclassmembers class *.R$ {
public static ;
}
We’re keeping the static fields of referenced inner classes of auto-generated R classes, just in case your code is accessing those fields by introspection. Note that the compiler already inlines primitive fields, so ProGuard can generally remove all these classes entirely anyway (because the classes are not referenced and therefore not required).
大体意思:
保留R文件,让运行环境可以通过introspection可以进行访问。
评论:
只要是安卓项目,这个必填。
-dontwarn android.support.**
首先解释一下:
-dontwarn [class_filter]
Specifies not to warn about unresolved references and other important problems at all. The optional filter is a regular expression; ProGuard doesn’t print warnings about classes with matching names. Ignoring warnings can be dangerous. For instance, if the unresolved classes or class members are indeed required for processing, the processed code will not function properly. Only use this option if you know what you’re doing!
大体意思:
匹配的类,没有找到的引用和其他重要的问题不进行提示。
评论:
通常情况下,这个是不选的。但是对于android.support.**这个必填。如果程序在debug版本运行正常,打包总是搞错,就应该屏蔽了,参照下文打包常见问题。
-dontwarn android.support.**
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.

下面补充一些常用命令:

-libraryjars class_path
Specifies the library jars (or aars, wars, ears, zips, apks, or directories) of the application to be processed. The files in these jars will not be included in the output jars. The specified library jars should at least contain the class files that are extended by application class files. Library class files that are only called needn’t be present, although their presence can improve the results of the optimization step. The entries in the class path can be filtered, as explained in the filters section. For better readability, class path entries can be specified using multiple -libraryjars options.
大体意思:
用于指定应用程序要使用的jar包。这些jar包里面的文件将不会包含在输入的jar包里面。指定的jar包中至少要包含应用类文件的父类。仅仅是在应用程序中有调用的jar包,没有必要放在这里。尽管添加上他们能够加快优化的速度。正如过滤章节讲的,class path指定的实体可以进行过滤。为了更好的可读性,class path实体可以通过多个-libraryjars进行添加。
评论:
如果整个APP的代码已经不知道是否集成了jar中的某些类的时候,就将所有的jar包都添加上吧。
Please note that the boot path and the class path set for running ProGuard are not considered when looking for library classes. This means that you explicitly have to specify the run-time jar that your code will use. Although this may seem cumbersome, it allows you to process applications targeted at different run-time environments. For example, you can process J2SE applications as well as JME midlets or Android apps, just by specifying the appropriate run-time jar.
大体意思:
注意:查找类库时,设置运行ProGuard不会自动查找引导路径和环境 变量中配置的class path。这也就意味着你必须明确的指定run-time ,你需要的jar包。尽管这样看起来很笨重,但是这样可以你可以处理面向不同run-time环境的应用。例如,通过指定恰当的run-time jar包,你可以分别处理J2SE应用、JME和安卓APP应用。
-repackageclasses [package_name]
Specifies to repackage all class files that are renamed, by moving them into the single given package. Without argument or with an empty string (”), the package is removed completely. This option overrides the -flattenpackagehierarchy option. It is another example of further obfuscating package names. It can make the processed code even smaller and less comprehensible. Its deprecated name is -defaultpackage. Only applicable when obfuscating.
大体意思:
将所有重命名的文件移动到一个单独的package中,如果没有指定package_name或者指定为‘’,重命名的文件将不再有package 。这个关键词复写了-flattenpackagehierarchy.这是另一个深度模糊package name的例子。它可以是处理后的代码更小、更难以理解。它的一个deprecated版本是-defaultpackage.只有模糊的时候,才会引用这个key。
Counter-indication: classes that look for resource files in their package directories will no longer work properly if they are moved elsewhere. When in doubt, just leave the packaging untouched by not using this option.
大体意思:
特别注意:将类移动到其他包之后,在package文件夹下查找资源文件的类将不能正常工作。如果有疑问,不要使用这个关键词。
-allowaccessmodification
Specifies that the access modifiers of classes and class members may be broadened during processing. This can improve the results of the optimization step. For instance, when inlining a public getter, it may be necessary to make the accessed field public too. Although Java’s binary compatibility specifications formally do not require this (cfr. The Java Language Specification, Third Edition, Section 13.4.6), some virtual machines would have problems with the processed code otherwise. Only applicable when optimizing (and when obfuscating with the -repackageclasses option).
大体意思:
在处理过程中,访问的类和类成员的作用域可以进行扩大。这个可以提高优化的效率。例如:当内联一个public的getter,使需要访问的field变成public是非常必要的。虽然Java的二进制兼容性说明文档正式声明不需要(”将内联时将field的访问权限设置为public“)。否则,一些虚拟机将不能够正确处理处理后的代码。只有优化的时候才会使用。
Counter-indication: you probably shouldn’t use this option when processing code that is to be used as a library, since classes and class members that weren’t designed to be public in the API may become public.
大体意思:
注意:如果你的项目目标是创建一个类库,那就不应该使用这个key,因为在API中原本不是public的类和类的field可以变成public。
-assumenosideeffects class_specification
Specifies methods that don’t have any side effects (other than maybe returning a value). In the optimization step, ProGuard will then remove calls to such methods, if it can determine that the return values aren’t used. ProGuard will analyze your program code to find such methods automatically.
It will not analyze library code, for which this option can therefore be useful. For example, you could specify the method System.currentTimeMillis(), so that any idle calls to it will be removed. With some care, you can also use the option to remove logging code.
Note that ProGuard applies the option to the entire hierarchy of the specified methods. Only applicable when optimizing. In general, making assumptions can be dangerous; you can easily break the processed code. Only use this option if you know what you’re doing!
大体意思:
指定没有任何副作用的方法(不同于可能返回值)。如果该方法的返回值没有使用,在优化阶段,Proguard将不调用这个方法。ProGuard将自动分析、定位这样的方法。它不会分析类库代码,这个option可以非常有用。例如:如果你指定System.currentTimeMillis(),那么所有空闲调用这个方法的都要删除。同样,使用这个option删除打印log信息的代码。
注意该option会应用于整个方法的层次结构。通常情况下,做出这样的假设是非常危险的,很容易导致APP崩溃。只有非常了解option的意义后,才建议使用。
Removing logging code
You can let ProGuard remove logging code. The trick is to specify that the logging methods don’t have side-effects — even though they actually do, since they write to the console or to a log file. ProGuard will take your word for it and remove the invocations (in the optimization step) and if possible the logging classes and methods themselves (in the shrinking step).
For example, this configuration removes invocations of the Android logging methods:

-assumenosideeffects class android.util.Log {    public static boolean isLoggable(java.lang.String, int);    public static int v(...);    public static int i(...);    public static int w(...);    public static int d(...);    public static int e(...);}

The wildcards are a shortcut to match all versions of the methods.
Note that you generally can’t remove logging code that uses System.out.println, since you would be removing all invocations of java.io.PrintStream#println, which could break your application. You can work around it by creating your own logging methods and let ProGuard remove those.
指定屏蔽打印log信息的方法没有不好的影响,可以让ProGuard删除打印log信息的代码。例如,下面的配置可以删除Andorid中的打印log信息的方法。但是请注意,不能删除使用System.out.println打印的log信息,因为这样将删除所有调用java.io.PrintStream#println,而这样有可能让你的应用崩溃。作为一个折中的方法,你可以定义自己的打印log的方法,使用这个option进行删除。

2.Proguard通配符

‘%’ for any primitive type.代码基本类型
‘?’ for a single character:任意字符。
* matches any part of a method name. OR matches any part of a class name not containing the package separator.:方法名的任意部分,或者不包括package分隔符的任意类名。
** matches any part of a class name, possibly containing any number of package separators. 匹配类名的任意一部分,可以包括package分隔符。
*** matches any type (primitive or non-primitive, array or non-array).:匹配任意类型(基本类型或者非基本类型,数组或者非数组)。

3.打包常见问题

标题有点大了,其实就是我在N次打包中碰到的一些问题,查找的对应解决问题的办法。

1 .Warning: can’t find superclass or interface Warning: can’t find referenced class

下面是官方文档上的解释:
A class in one of your program jars or library jars is referring to a class or interface that is missing from the input. The warning lists both the referencing class(es) and the missing referenced class(es). There can be a few reasons, with their own solutions:
在你程序中或libary jar中一个class 引用了一个the input中不存在的class or interface.警告信息罗列了参考的类和丢失的被参考的类。这有几个原因,有他们想对应的解决方式:
1.If the missing class is referenced from your own code, you may have forgotten to specify an essential library. Just like when compiling all code from scratch, you must specify all libraries that the code is referencing, directly or indirectly. If the library should be processed and included in the output, you should specify it with -injars, otherwise you should specify it with -libraryjars.
For example, if ProGuard complains that it can’t find a java.lang class, you have to make sure that you are specifying the run-time library of your platform. For JSE, these are typically packaged in lib/rt.jar (vm.jar for IBM’s JVM, and classes.jar in MacOS X). Other platforms like JME and Android have their own run-time libraries. The examples section provides more details for the various platforms.
如果是你写的代码不能够获取引用,有可能是你忘记指定某个libary了。正如从头编译,你必须直接或间接的指定你的代码引用的所有libary。如果libary 需要处理、放入the output,你应该使用-injars来指定它,否则,你应该使用-libraryjars来指定它。例如,如果Proguard提示不能够找到java.lang.class,你就要检查一下,你是否指定了平台的run-time libary。对于JAVASE,是lib/rt.jar(IBM JVM 的vm.jar,MacOS X的classes.jar).其他平台像JME和Android有他们自己的run-time libaries.
If ProGuard still complains that it can’t find a javax.crypto class, you probably still have to specify jce.jar, next to the more common rt.jar.
如果Proguard依旧提示不能找到javax.crypto类,就需要将和rt.jar在同一个路径下的jce.jar添加进来了。
2.If the missing class is referenced from a pre-compiled third-party library, and your original code runs fine without it, then the missing dependency doesn’t seem to hurt. The cleanest solution is to filter out the referencing class or classes from the input, with a filter like “-libraryjars mylibrary.jar(!somepackage/SomeUnusedReferencingClass.class)”.
如果没有找到引用的类是预编译的第三方libary,debug模式时,代码运行正常,这时候丢失的dependency没有什么不利的。最整洁的解决方式是使用filter从the input中过滤掉引用的类.eg:-libraryjars mylibrary.jar(!somepackage/SomeUnusedReferencingClass.class).
ProGuard will then skip this class entirely in the input, and it will not bump into the problem of its missing reference. However, you may then have to filter out other classes that are in turn referencing the removed class. In practice, this works best if you can filter out entire unused packages at once, with a wildcard filter like “-libraryjars mylibrary.jar(!someunusedpackage/**)”.
Proguard将会在the input中忽略整个类,当然也就不会提示他引用的某个类缺失的警告信息。然而,你同时必须处理所有引用这个类的类。在应用中,最好使用通配符eg. “-libraryjars mylibrary.jar(!someunusedpackage/**)”,一次过滤掉整个包.
3.If you don’t feel like filtering out the problematic classes, you can try your luck with the -ignorewarnings option, or even the -dontwarn option. Only use these options if you really know what you’re doing though.
如果你不喜欢过滤掉有问题的类,可以尝试使用 -ignorewarnings 或者 -dontwarn,只有非常明白你在做什么,再使用这两个 option。
The standard Android build process automatically specifies the input jars for you. Unfortunately, many pre-compiled third-party libraries refer to other libraries that are not actually used and therefore not present. This works fine in debug builds, but in release builds, ProGuard expects all libraries, so it can perform a proper static analysis. For example, if ProGuard complains that it can’t find a java.awt class, then some library that you are using is referring to java.awt
标准的Android构建过程将自动为你指定the input jars。不好的是,很多预编译的第三方libraries涉及了一些因为没有使用而没有显现的其他libraries。debug模式的时候正常工作,在release 构建的时候,ProGuard要获取全部的libary,用来进行一个合理的全局分析。例如:如果ProGuard提示不能找到java.awt 类,也就说明了你使用的一些类库引用了java.awt。
This is a bit shady, since Android doesn’t have this package at all, but if your application works anyway, you can let ProGuard accept it with “-dontwarn java.awt.**”, for instance.
因为Android中根本没有这个包,所有是很难办的。如果你的应用可以正常运行,你可以使用 “-dontwarn java.awt.**”,屏蔽掉这种提示信息。
If the missing class is an Android run-time class, you should make sure that you are building against an Android run-time that is sufficiently recent. You may need to change the build target in your project.properties file or build.gradle file to that recent version. You can still specify a different minSdkVersion and a different targetSdkVersion in your AndroidManifest.xml file.
如果丢失的是一个Android run-time类,就要确认一下Android run-time版本是不是最够高。或许需要在project.properties 文件或者build.gradle文件中修改构建的版本。你也可以在AndroidManifest.xml文件中指定不同的minSdkVersion 或 targetSdkVersion.

2.Warning: can’t write resource … Duplicate zip entry

Your input jars contain multiple resource files with the same name. ProGuard continues copying the resource files as usual, skipping any files with previously used names. Once more, the warning may be an indication of some problem though, so it’s advisable to remove the duplicates. A convenient way to do so is by specifying filters on the input jars. There is no option to switch off these warnings.
The standard Android build process automatically specifies the input jars for you. There may not be an easy way to filter them to remove these warnings. You could remove the duplicate resource files manually from the input and the libraries.
在你的要打包的文件中存在多个文件名相同的资源文件。ProGuard复制资源文件的时候会跳过已经复制过相同文件名的资源文件。进一步,这个警告可能是存在的一些问题的提示,建议将重名的资源文件进行手动删除。没有-option可以关闭这些警告。
标准的Android构建过程自动指定输入的jar。没有简单的方式删除这些警告。你可以从input jars和你用到的libaries中将这些资源文件手动删除。

3.参考官网常见问题集锦

http://proguard.sourceforge.net/index.html#manual/troubleshooting.html

4.啰嗦一下我碰到的一些问题

1.保证APP在debug模式可以完全正常运行的情况下,如果打包的时候控制台打印这样的错误:[2016-03-10 08:36:15 - XXX] Warning: jfoundation.dataobject.classes.JParamObject: can’t find referenced class org.jdom.Element
直接使用-dontwarn jfoundation.**
将所有这种类型的警告都使用-dontwarn 进行添加.
2.屏蔽APP中打印的所有的敏感信息
屏蔽所有的Log信息
-assumenosideeffects class android.util.Log {
public static * d(…);
public static * v(…);
public static * i(…);
public static * w(…);
public static * e(…);
}
3.Eclipse打包错误
[2016-03-11 17:42:46 - ddms] null
java.nio.BufferOverflowException
at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:206)
at com.android.ddmlib.JdwpPacket.movePacket(JdwpPacket.java:235)
at com.android.ddmlib.Debugger.sendAndConsume(Debugger.java:347)
at com.android.ddmlib.Client.forwardPacketToDebugger(Client.java:665)
at com.android.ddmlib.MonitorThread.processClientActivity(MonitorThread.java:344)
at com.android.ddmlib.MonitorThread.run(MonitorThread.java:263)
解决办法,clean之后,重新打包。

4.APP中使用了Reflection和远程过程调用(进程通信)
需要将用到了class和interface等统统添加进去:
-keep class com.pansoft.mediaplayer.PansoftAudioServiceController{ *; }
-keep interface com.pansoft.mediaplayer.IAudioService{*;}
如果还是报错误,找不到xx类,就将其所在的package添加进去如下:
-keep public interface com.pansoft.mediaplayer.**
-keep public class com.pansoft.mediaplayer.**

4.定义一个模板

#精简一篇可以快速修改的Proguard模板-dontusemixedcaseclassnames-dontskipnonpubliclibraryclassmembers-verbose-dontoptimize-dontpreverify-keepattributes *Annotation*-keepclasseswithmembernames class * { native <methods>; }-keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); }#保留系统自带的签名的内容-keepattributes Signature#处理页面中的JS调用的-keepattributes JavascriptInterface-keepclassmembers class * {    @android.webkit.JavascriptInterface <methods>;}-keepclassmembers class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator CREATOR; }-keep public class * implements java.io.Serializable -keepclassmembers class **.R$* { public static <fields>; }#为了让在xml中使用的组件,可以定位到组件定义的位置;-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*(...);}#这个应该和Activity中的类似,防止在xml定义的事件无法响应;-keepclassmembers class * extends android.content.Context {   public void *(android.view.View);   public void *(android.view.MenuItem);}#Proguard混淆的是java文件,对于manifest中注册的组件,重命名后,无法定位到组件和Application-keepnames   public class * extends android.app.Activity -keepnames public class * extends android.app.Application -keepnames public class * extends android.app.Service -keepnames public class * extends android.content.BroadcastReceiver -keepnames public class * extends android.content.ContentProvider #屏蔽所有的Log信息 -assumenosideeffects class android.util.Log {    public static *** d(...);    public static *** v(...);    public static *** i(...);    public static *** w(...);    public static *** e(...);}-dontwarn android.support.**#下面的这些不是固定的,打包出现"Warning: can't find referenced class",就将相应的部分添加进去(必须确保APP在debug模式运行正常)-dontwarn com.core.xml.**-dontwarn com.google.gson.**-dontwarn okio.Okio.**-dontwarn org.apache.**-dontwarn java.**-dontwarn org.jdom.**-dontwarn org.codehaus.**#涉及reflection和远程过程调用的都全部保留(包括其所在的包)-keep  public class com.pansoft.mediaplayer.** -keep class com.pansoft.mediaplayer.PansoftAudioServiceController{ *; }-keep interface com.pansoft.mediaplayer.IAudioService{*;}

5.APP崩溃后,如何还原崩溃日志的问题

通过{sdk-dir}\tools\proguard\bin目录下的retrace.bat工具反混淆,执行命令:retrace.bat -verbose mapping.txt obfuscated_tract.txt > out_tract.txt。

如果提示Java不是内部命令,看一下是不是配置了java的class path,如果和我一样,在管理员模式下执行命令提示符,再试一下。

更多相关文章

  1. Android中shape的使用大全
  2. Android(安卓)- Rerofit-RxJava(转载)
  3. android Toolbar的使用结合状态栏与返回键
  4. Android(安卓)使用WebView
  5. 考虑Android向后兼容的几条黄金法则
  6. Android(安卓)ApiDemos示例解析(160):Views->Layouts->TableLayo
  7. 箭头函数的基础使用
  8. NPM 和webpack 的基础使用
  9. Python list sort方法的具体使用

随机推荐

  1. android - DefaultHttpClient设置超时.
  2. Android(安卓)Studio1.5 配置Android(安
  3. Android(安卓)AsyncTask
  4. android anim 动画效果
  5. 移动开发:Android(安卓)错误警告信息解释
  6. Android(安卓)studio3.0 - 解决创建Java
  7. android用户界面之按钮(Button)教程实例
  8. Android退出应用最优雅的方式(改进版)
  9. Android旋转动画
  10. OpenGL ES教程III之移动变换(原文对照)