学习路线:
1.看developer对于代码混淆的介绍:http://developer.android.com/tools/help/proguard.html. 很短,大概20分钟看完(我只看了ant编译的部分)。核心点:
a, 背景。原来proguard不仅是代码混淆,还能通过去掉无用代码减少代码体积,对代码做优化
b, 一定要记得,为每个release版本保存mapping.txt! 非常重要,否则可能无法还原之前版本的trace!
c,具体的proguard使用,参见http://stuff.mit.edu/afs/sipb/project/android/sdk/android-sdk-linux/tools/proguard/docs/index.html#manual/introduction.html
2. 去看proguard手册:http://stuff.mit.edu/afs/sipb/project/android/sdk/android-sdk-linux/tools/proguard/docs/index.html#manual/introduction.html。 导读:
a,"Input/output options” 这一节要看完。估计花费15分钟
b,重点看-keep Options.花点时间把class specification这部分看完。其他部分可以暂时不看。看到这里,对于基本的规则已经比较清楚了,那么问题来了,对于android,有没有一套一般性的规则呢?哪些class要keep住?
看到这里不得不骂一下谷歌,文档居然没提这茬。 再看看proguard的example:https://stuff.mit.edu/afs/sipb/project/android/sdk/android-sdk-linux/tools/proguard/docs/index.html#manual/examples.html
这里面重要的几句话:
Most importantly, we‘re keeping all fundamental classes that may be referenced by the AndroidManifest.xml
file of the application. If your manifest file contains other classes and methods, you may have to specify those as well. ------在manifest中提到的class要keep。例如activity,broadcastreceiver, service, contentprovider等等。
We‘re keeping annotations, since they might be used by custom RemoteViews --------remoteview没用过,不知道有何影响
We‘re keeping any custom View
extensions and other classes with typical constructors, since they might be referenced from XML layout files. -------在layout中可能引用的类要keep
We‘re also keeping the required static fields in Parcelable
implementations, since they are accessed by introspection. --------实现parceble的要keep住. 因为传递参数后要还原parceble对象的一些内部成员
If applicable, you should add options for processing native methods, callback methods, enumerations, and resource files. --------native,回调等要keep住。估计这些类并没有明显的被调用,怕被优化时误杀。
View的几种构造函数也要保护,因为他们在代码中并没有显式地被调用。
-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*(...); }
可以总结出需要被keep的类/方法/字段的原则:
1, 在XML等外部配置文件中引用名字的。原因:如果是类之间相互引用,proguard是知道的,被混淆后也可以找到类,但是外部引用proguard是不知道的。如果被proguard混淆了,外部引用就找不到对应类了
2,在代码中没有显式调用的函数(就是你用“open call hierarchy"结果为空的),比如native方法,系统回调,反射的函数,改了名字后就找不到类了。
原文:http://www.cnblogs.com/jackhuwei/p/5016453.html