1、下载jocky,解压后把整个文件夹复制到Eclipse的plugin目录。
2、重启Eclipse,在项目上点右键,如果出现jocky菜单,则安装成功。
3、在项目上点右键,选菜单jocky->jocky setting,弹出菜单后设置如图
4、点ok后,将在项目的根目录下生成一个jocky_build.xml文件,事实上是一个ant build文件。打开这个文件,作适当修改
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- WARNING: Jocky autogenerated file.
Any modifications will be overwritten.
-->
<project basedir="." default="build" name="iSzmap.Android.public.jocky">
<property name="jocky.jar" value="D:\eclipse-jee-galileo-SR1-win32-2\eclipse\plugins\org.apusic.jocky_1.0.3\jocky.jar"/>
<property name="jocky.output.dir" value="iszmap"/>
<property name="jocky.scramble.level" value="package"/>
<property name="target" value="1.5"/>
<path id="project.classpath">
<pathelement location="bin"/>
<pathelement location="D:/android-sdk-windows-1.5_r3/platforms/android-1.5/android.jar"/>
</path>
<target name="init">
<jocky jar="${jocky.jar}" level="${jocky.scramble.level}"/>
<mkdir dir="${jocky.output.dir}"/>
<mkdir dir="${jocky.output.dir}/bin"/>
</target>
<target name="clean">
<delete dir="${jocky.output.dir}/bin"/>
<delete dir="${jocky.output.dir}"/>
</target>
<target depends="init" name="build">
<echo message="${ant.project.name}: ${ant.file}"/>
<jocky enable="true"/>
<javac destdir="${jocky.output.dir}/bin" target="${target}" encoding="UTF-8">
<src path="src/com/iszmap/android/map"/>
<classpath refid="project.classpath"/>
</javac>
</target>
</project>
注意红色的部分,第一部分是添加编译时需要的额外的类包;第二部分是设定java源文件的编码,如果您的文件中有中文的话,必须设定编码;第三部分是设定源文件的目录,因为有时候我们只想输出src目录下的部分包而不是全部。
5、保存后选jocky-jocky Now就可以进行混码了。
混码后的class文件可以通过命令进行打包,或用winrar进行压缩,注意必须压成.zip文件而不是.rar文件。
二、
使用jocky的时候,如果你的java文件使用了utf-8编码,而windows默认是gbk编码,可能会出现"unmappable character for encoding GBK"错误而导致jocky不能使用的情况。可以通过修改jocky_build.xml中的javac段,为其添加encoding="UTF-8"就可以解决这个问题了。
这个问题的实质原因是因为ant的javac使用了默认编码(如果你使用windows xp中文版,默认编码就是GBK),从而导致编码不一致。
<javac destdir="${jocky.output.dir}/WebRoot/WEB-INF/classes" target="${target}" encoding="UTF-8">
<src path="src"/>
<classpath refid="project.classpath"/>
</javac>
jocky下载:
http://www.pudn.com/downloads133/sourcecode/others/detail567839.html
当你将这些都搞到了之后,运行你的android项目,然后从bin文件夹中拷贝出你的apk文件,用我上一章说的apk反编译一下,查看是不是有一大堆的不搭边的.java文件,这表示被混淆了,祝你好运,如果成功的话如图所示:
作为Android应用开发者,不得不面对一个尴尬的局面,就是自己辛辛苦苦开发的应用可以被别人很轻易的就反编译出来。
Google似乎也发现了这个问题,从SDK2.3开始我们可以看到在android-sdk-windows\tools\下面多了一个proguard文件夹
proguard是一个java代码混淆的工具,通过proguard,别人即使反编译你的apk包,也只会看到一些让人很难看懂的代码,从而达到保护代码的作用。
下面具体说一说怎么样让SDK2.3下的proguard.cfg文件起作用,先来看看android-sdk-windows\tools\lib\proguard.cfg的内容:
01 | -optimizationpasses 5 |
02 | -dontusemixedcaseclassnames |
03 | -dontskipnonpubliclibraryclasses |
04 | -dontpreverify |
05 | -verbose |
06 | -optimizations !code/simplification/arithmetic,!field/*,! class /merging/* |
07 |
08 | -keep public class * extends android.app.Activity |
09 | -keep public class * extends android.app.Application |
10 | -keep public class * extends android.app.Service |
11 | -keep public class * extends android.content.BroadcastReceiver |
12 | -keep public class * extends android.content.ContentProvider |
13 | -keep public class * extends android.app.backup.BackupAgentHelper |
14 | -keep public class * extends android.preference.Preference |
15 | -keep public class com.android.vending.licensing.ILicensingService |
16 |
17 | -keepclasseswithmembernames class * { |
18 | native <methods>; |
19 | } |
20 |
21 | -keepclasseswithmembernames class * { |
22 | public <init>(android.content.Context, android.util.AttributeSet); |
23 | } |
24 |
25 | -keepclasseswithmembernames class * { |
26 | public <init>(android.content.Context, android.util.AttributeSet, int ); |
27 | } |
28 |
29 | -keepclassmembers enum * { |
30 | public static **[] values(); |
31 | public static ** valueOf(java.lang.String); |
32 | } |
33 |
34 | -keep class * implements android.os.Parcelable { |
35 | public static final android.os.Parcelable$Creator *; |
36 | } |
从脚本中可以看到,混淆中保留了继承自Activity、Service、Application、BroadcastReceiver、 ContentProvider等基本组件以及com.android.vending.licensing.ILicensingService,
并保留了所有的Native变量名及类名,所有类中部分以设定了固定参数格式的构造函数,枚举等等。(详细信息请参考<proguard_path>/examples中的例子及注释。)
让proguard.cfg起作用的做法很简单,就是在eclipse自动生成的default.properties文件中加上一句“proguard.config=proguard.cfg”就可以了
完整的default.properties文件应该如下:
01 | # This file is automatically generated by Android Tools. |
02 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! |
03 | # |
04 | # This file must be checked in Version Control Systems. |
05 | # |
06 | # To customize properties used by the Ant build system use, |
07 | # "build.properties" , and override values to adapt the script to your |
08 | # project structure. |
09 |
10 | # Project target. |
11 | target=android- 9 |
12 | proguard.config=proguard.cfg |
大功告成,正常的编译签名后就可以防止代码被反编译了。反编译经过代码混淆的apk得到的代码应该类似于下面的效果,是很难看懂的:
如果您使用的是2.3之前的SDK版本也没关系,把上面的proguard.cfg文件复制一份放到项目中,然后进行相同的操作即可
原文出处:http://blog.csdn.net/sunboy_2050/article/details/6727640
ProGuard简介
ProGuard是一个SourceForge上非常知名的开源项目。官网网址是:http://proguard.sourceforge.net/。
Java的字节码一般是非常容易反编译的。为了很好的保护Java源代码,我们往往会对编译好的class文件进行混淆处理。ProGuard的主要作用就是混淆。当然它还能对字节码进行缩减体积、优化等,但那些对于我们来说都算是次要的功能。
Android Eclipse开发环境与ProGuard
在Android 2.3以前,混淆Android代码只能手动添加proguard来实现代码混淆,非常不方便。而2.3以后,Google已经将这个工具加入到了SDK的工具集里。具体路径:SDK\tools\proguard。当创建一个新的Android工程时,在工程目录的根路径下,会出现一个proguard的配置文件proguard.cfg。也就是说,我们可以通过简单的配置,在我们的elipse工程中直接使用ProGuard混淆Android工程。
具体混淆的步骤非常简单。首先,我们需要在工程描述文件default.properties中,添加一句话,启用ProGuard。如下所示:
01 | # This file is automatically generated by Android Tools. |
02 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! |
03 | # |
04 | # This file must be checked in Version Control Systems. |
05 | # |
06 | # To customize properties used by the Ant build system use, |
07 | # "ant.properties", and override values to adapt the script to your |
08 | # project structure. |
09 |
10 | # Project target. |
11 | target=android-8 |
12 | proguardproguard.config=proguard.cfg |
这样,Proguard就可以使用了。当我们正常通过Android Tools导出Application Package时,Proguard就会自动启用,优化混淆你的代码。
导出成功后,你可以反编译看看混淆的效果。一些类名、方法名和变量名等,都变成了一些无意义的字母或者数字。证明混淆成功!
proguard.cfg配置
稍微深入想一下混淆后的结果,你就会发现,如果一些提供给外部的类、方法、变量等名字被改变了,那么程序本身的功能就无法正常实现。那么Proguard如何知道哪些东西是可以改名,而哪些是不能改变的呢?
这个是靠proguard.cfg文件来进行配置的。Android工程中默认自动生成的proguard.cfg已经针对Android的一般情况进行了配置,我们打开这个配置文件。内容大概如下:
01 | -optimizationpasses 5 |
02 | -dontusemixedcaseclassnames |
03 | -dontskipnonpubliclibraryclasses |
04 | -dontpreverify |
05 | -verbose |
06 | -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* |
07 |
08 | -keep public class * extends Android.app.Activity |
09 | -keep public class * extends android.app.Application |
10 | -keep public class * extends android.app.Service |
11 | -keep public class * extends android.content.BroadcastReceiver |
12 | -keep public class * extends android.content.ContentProvider |
13 | -keep public class * extends android.app.backup.BackupAgentHelper |
14 | -keep public class * extends android.preference.Preference |
15 | -keep public class com.android.vending.licensing.ILicensingService |
16 |
17 | -keepclasseswithmembernames class * { |
18 | native <methods>; |
19 | } |
20 |
21 | -keepclasseswithmembers class * { |
22 | public <init>(android.content.Context, android.util.AttributeSet); |
23 | } |
24 |
25 | -keepclasseswithmembers class * { |
26 | public <init>(android.content.Context, android.util.AttributeSet, int); |
27 | } |
28 |
29 | -keepclassmembers class * extends android.app.Activity { |
30 | public void *(android.view.View); |
31 | } |
32 |
33 | -keepclassmembers enum * { |
34 | public static **[] values(); |
35 | public static ** valueOf(java.lang.String); |
36 | } |
37 |
38 | -keep class * implements android.os.Parcelable { |
39 | public static final android.os.Parcelable$Creator *; |
40 | } |
它主要保留了继承自Activity、Application、Service、BroadcastReceiver、 ContentProvider、BackupAgentHelper、Preference和ILicensingService的子类。因为这些子类,都是可能被外部调用的。
另外,它还保留了含有native方法的类、构造函数从xml构造的类(一般为View的子类)、枚举类型中的values和valueOf静态方法、继承Parcelable的跨进程数据类。
在实际的一个工程项目中,可能Google自动生成的配置不能胜任我们的混淆工作。所以,我们往往需要自己编写一些ProGuard配置。这方面的资料在官网的Manual -> Usage里有详细说明,大家可以研究一下。
1 . 在工程文件project.properties中加入下proguard.config=proguard.cfg , 如下所示:
target=android-8
proguard.config=proguard.cfg
Eclipse会通过此配置在工程目录生成proguard.cfg文件
2 . 生成keystore (如已有可直接利用)
按照下面的命令行 在D:\Program Files\Java\jdk1.6.0_07\bin>目录下,输入keytool -genkey -alias android.keystore -keyalg RSA -validity 100000 -keystore android.keystore
参数意义:-validity主要是证书的有效期,写100000天;空格,退格键 都算密码。
命令执行后会在D:\Program Files\Java\jdk1.6.0_07\bin>目录下生成 android.keystore文件。
3. 在Eclipce的操作
File -> Export -> Export Android Application -> Select project -> Using the existing keystore , and input password -> select the destination APK file
经过混淆后的源代码,原先的类名和方法名会被类似a,b,c。。。的字符所替换,混淆的原理其实也就是类名和方法名的映射。
但4大组件并没有混淆(所有在清单文件定义的组件不能被混淆),因为系统需要通过清单文件来查找和运行应用程序。
proguard.cfg 文件代码解读
-optimizationpasses 5 ->设置混淆的压缩比率 0 ~ 7
-dontusemixedcaseclassnames -> Aa aA
-dontskipnonpubliclibraryclasses ->如果应用程序引入的有jar包,并且想混淆jar包里面的class
-dontpreverify
-verbose ->混淆后生产映射文件 map 类名->转化后类名的映射
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* ->混淆采用的算法.
-keep public class * extends android.app.Activity ->所有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
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>; -> 所有native的方法不能去混淆.
}
-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 { -> aidl文件不能去混淆.
public static final android.os.Parcelable$Creator *;
}