如何在Eclipse中使用Proguard对Android库(.jar文件)进行混淆

我见过很多关于如何在Eclipse中使用ProGuard模糊Android应用程序(.apk文件)的文章。 另请参阅http://developer.android.com/guide/developing/tools/proguard.html :

“在发布模式下构build应用程序时,无论是通过运行Ant版本还是使用Eclipse中的导出向导,构build系统都会自动检查proguard.config属性是否已设置,如果是,ProGuard会自动处理应用程序的字节码在将所有内容打包成.apk文件之前“。

但是,如果使用Eclipse导出向导在.jar文件中导出Android项目,请按照所述的步骤(创build文件proguard.cfg,将proguard.config属性configuration为文件default.properties中的proguard.cfg,使用导出向导等等)似乎并没有工作 – 我看到在所得到的jar文件中没有混淆类名等。 我也有我的proguard.cfg文件中的以下设置,但我没有看到任何输出文件在我的项目目录或在proguard目录(该目录甚至没有创build)。

-dump class_files.txt -printseeds seeds.txt -printusage unused.txt -printmapping mapping.txt 

我甚至在我的项目目录中创build了一个文件project.properties,下面这行代码似乎并没有引起ProGuard的注意:

 proguard.config=proguard.cfg 

这个项目没有定义任何活动。 我在Windows上使用Android 2.3.1和Eclipse Galileo 3.5.2。 与Android 3.0相同的结果。 似乎混淆步骤必须以某种方式在Eclipse导出向导中显式插入。 我会感谢任何帮助或见解。 谢谢。

Solutions Collecting From Web of "如何在Eclipse中使用Proguard对Android库(.jar文件)进行混淆"

正如在上面的答案之一的评论中所build议的(但是我起初没有注意到,因为它被埋在了其中一个“额外的评论”中)…

我们只需在eclipse之外的库上的命令行上运行progruard( 参见下面的第一个块 ),在我们的proguard.cfg文件中使用下面第二个块中的参数(并且绝对不要使用-dontpreverify或使用您的项目项目作为一个Android库将无法正确混淆由于从您的project.jar StackMapTable问题)。

命令行:

 $ java -jar $ANDROID_SDK/tools/proguard/lib/proguard.jar \ -libraryjars $ANDROID_SDK/platforms/android-18/android.jar @proguard.cfg -outjars /tmp/project.jar -verbose 

proguard.cfg:

 -optimizationpasses 5 -dontusemixedcaseclassnames -dontskipnonpubliclibraryclasses -dontwarn our.company.project.R* -injars bin/project.jar -verbose -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* -keep class org.apache.3rdparty.stuff.** -keep public class our.company.project.ProjectAPI -keep public class * extends android.app.Activity -keep public class * extends android.app.Application -keep public class * extends android.app.Service -keep public class * extends android.content.BroadcastReceiver -keep public class * extends android.content.ContentProvider -keep public class * extends android.app.backup.BackupAgentHelper -keep public class * extends android.preference.Preference -keepclassmembers public class our.company.project.ProjectAPI { public static <fields>; } -keepclasseswithmembernames class * { native <methods>; } -keepclasseswithmembers class * { public <init>(android.content.Context, android.util.AttributeSet); } -keepclasseswithmembers class * { public <init>(android.content.Context, android.util.AttributeSet, int); } -keepclassmembers class * extends android.app.Activity { public void *(android.view.View); } -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); } -keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; } 

可能并不是所有的参数和-keep项都是必须的(除了没有像前面提到的那样使用-dontpreverify ),但是对于我来说,其中的大部分对于我来说都是有意义的,如果你有一个Activity类扩展你正在出口的图书馆。

我用一个间接的方法来生成一个导出的android混淆jar,我的方法是:

  1. 导出一个签名的apk使用eclipse

  2. 解压apk,findclasses.dex

  3. 使用dex2jar.bat,将classes.dex改为jar

  4. 解压缩jar并删除不需要的类,然后将其压缩并将文件名更改为XXX.jar

  5. 然后你在其他项目中使用这个jar,或者把它给客户,这是混淆!

我相信这会帮助你! 好好享受!

 java -jar proguard.jar @yourconfig.pro 

yourconfig.pro(从http://proguard.sourceforge.net/index.html#manual/examples.html扩展)&#xFF1A;

 -injars yourjar.jar -outjars yourjar_out.jar -libraryjars 'C:\android\sdk\platforms\android-10\android.jar' -printmapping mapping.txt -verbose -dontoptimize -dontpreverify -dontshrink -dontskipnonpubliclibraryclassmembers -dontusemixedcaseclassnames -keepparameternames -renamesourcefileattribute SourceFile -keepattributes Exceptions,InnerClasses,Signature,Deprecated, SourceFile,LineNumberTable,*Annotation*,EnclosingMethod -keep public class * { public protected *; } -keepclassmembernames class * { java.lang.Class class$(java.lang.String); java.lang.Class class$(java.lang.String, boolean); } -keepclasseswithmembernames class * { native <methods>; } -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); } -keepclassmembers class * implements java.io.Serializable { static final long serialVersionUID; private static final java.io.ObjectStreamField[] serialPersistentFields; private void writeObject(java.io.ObjectOutputStream); private void readObject(java.io.ObjectInputStream); java.lang.Object writeReplace(); java.lang.Object readResolve(); } 

结果可以用jd-gui来validation

调用ProGuard的方法非常简单:

  1. proguard.config=proguard.cfg行添加到project.properties
  2. 导出应用程序包

一个默认的proguard.cfg文件应该由新的项目向导自动创build。

不要混淆你的纯Java jar。 在生成Jar时完全跳过这个阶段(无论是在Eclipse中手动还是通过命令行的Ant构build)。

相反,在客户端项目中设置并执行适当的混淆处理,即使用Jar,将库添加为外部Jar。 Proguard也能够在Jar中混淆代码。

我偶然发现了这个问题,结果如我在这里所描述的那样成功了。