您的位置:首页 > 移动开发 > Android开发

Ant编译android,并Proguard代码混淆,v4混淆配置

2013-09-03 13:23 956 查看
忙了三四周,总算把购开心的ios版(appStore搜“购开心”)成功翻译成了android版,UI效果基本保持一致,上一张UI效果图吧,很养眼的:

























还不错吧,进入正题吧。

以前一直是让我徒弟混淆和打包的,这个就剩下我一个人了,弄了一次,时间太久了,还太麻烦了,于是,我就研究了下ant打包,下面就简单说下吧:

首先,做任何开发前,肯定是各种环境搭建和配置啊,ant的搭建很简单:

一、安装ant

到官方主页http://ant.apache.org下载新版(目前为Ant-1.9.2)的ant,得到的是一个apache-ant-1.8.1-bin.zip的压缩包。将其解压到你的硬盘上,例如:D:\Android\apache-ant-1.9.2

二、配置环境变量

window中设置ant环境变量:

ANT_HOME D:/Android/apache-ant-1.9.2

path D:/Android/apache-ant-1.9.2/bin

classpath D:/Android/apache-ant-1.9.2/lib

linux中设置ant环境变量:

root用户登陆,用vi编辑器修改root目录下的".bash_profile"属性文件,假设Ant安装在/user/local/ant目录下,要在文件的最后加上

"exportANT_HOME=/user/local/ant"和"export PATH=$PATH:$ANT_HOME/bin"

三、验证ant

为了验证ant是否成功安装,可以进行如下操作:

依次选择:开始->运行->cmd,输入如下命令:ant

如果出现如下内容,说明安装成功:

Buildfile: build.xml does not exist!

Build failed

当然,JAVA_HOME、ANDROID_SDK_HOME等的配置这里就不说了

四、我们就在项目中添加build.xml

code如下:

<?xml version="1.0" encoding="utf-8"?>
<project
name="HappyShopping"
default="release" >

<!-- ANT环境变量 -->

<property environment="env" />
<!-- 应用名称 -->

<property
name="appName"
value="${ant.project.name}" />
<!-- SDK目录(获取操作系统环境变量ANDROID_SDK_HOME的值) -->

<property
name="sdk-folder"
value="${env.ANDROID_SDK_HOME}" />
<!-- SDK指定平台目录 -->

<property
name="sdk-platform-folder"
value="${sdk-folder}/platforms/android-16" />
<!-- SDK中tools目录 -->

<property
name="sdk-tools"
value="${sdk-folder}/tools" />
<!-- SDK指定平台中tools目录 -->

<property
name="sdk-platform-tools"
value="${sdk-folder}/platform-tools" />

<!-- 使用到的命令(当前系统为windows,如果系统为linux,可将.bat文件替换成相对应的命令) -->

<property
name="aapt"
value="${sdk-platform-tools}/aapt" />

<property
name="aidl"
value="${sdk-platform-tools}/aidl" />

<property
name="dx"
value="${sdk-platform-tools}/dx.bat" />

<property
name="apkbuilder"
value="${sdk-tools}/apkbuilder.bat" />

<property
name="jarsigner"
value="${env.JAVA_HOME}/bin/jarsigner" />

<!-- 编译需要的jar; 如果项目使用到地图服务则需要maps.jar -->

<property
name="android-jar"
value="${sdk-platform-folder}/android.jar" />

<property
name="android-maps-jar"
value="${sdk-folder}/add-ons/addon_google_apis_google_inc_8/libs/maps.jar" />

<!-- 编译aidl文件所需的预处理框架文件framework.aidl -->

<property
name="framework-aidl"
value="${sdk-platform-folder}/framework.aidl" />

<!-- 生成R文件的相对目录 -->

<property
name="outdir-gen"
value="gen" />
<!-- 编译后的文件放置目录 -->

<property
name="outdir-bin"
value="bin" />

<!-- 清单文件 -->

<property
name="manifest-xml"
value="AndroidManifest.xml" />
<!-- 源文件目录 -->

<property
name="resource-dir"
value="res" />

<property
name="asset-dir"
value="assets" />
<!-- java源文件目录 -->

<property
name="srcdir"
value="src" />

<property
name="srcdir-ospath"
value="${basedir}/${srcdir}" />
<!-- 外部类库所在目录 -->

<property
name="external-lib"
value="libs" />

<property
name="external-lib-ospath"
value="${basedir}/${external-lib}" />

<!-- 生成class目录 -->

<property
name="outdir-classes"
value="${outdir-bin}" />

<property
name="outdir-classes-ospath"
value="${basedir}/${outdir-classes}" />

<!-- classes.dex相关变量 -->

<property
name="dex-file"
value="classes.dex" />

<property
name="dex-path"
value="${outdir-bin}/${dex-file}" />

<property
name="dex-ospath"
value="${basedir}/${dex-path}" />

<!-- 经过aapt生成的资源包文件 -->

<property
name="resources-package"
value="${outdir-bin}/resources.ap_" />

<property
name="resources-package-ospath"
value="${basedir}/${resources-package}" />

<!-- 未认证apk包 -->

<property
name="out-unsigned-package"
value="${outdir-bin}/${appName}-unsigned.apk" />

<property
name="out-unsigned-package-ospath"
value="${basedir}/${out-unsigned-package}" />

<!-- 证书文件 -->

<property
name="keystore-file"
value="${basedir}/naomi" />

<!-- 已认证apk包 -->

<property
name="out-signed-package"
value="${outdir-bin}/${appName}.apk" />

<property
name="out-signed-package-ospath"
value="${basedir}/${out-signed-package}" />

<!-- 代码混淆配置 -->
<property
name="proguard-home"
value="D:/Android/android-sdk-windows/tools/proguard/lib" />

<target name="init" >

<echo>
Initializing all output directories...
</echo>

<delete dir="${outdir-bin}" />

<mkdir dir="${outdir-bin}" />

<mkdir dir="${outdir-classes}" />
</target>

<!-- 根据工程中的资源文件生成R.java文件 -->

<target
name="gen-R"
depends="init" >

<echo>
Generating R.java from the resources...
</echo>

<exec
executable="${aapt}"
failonerror="true" >

<arg value="package" />

<arg value="-f" />

<arg value="-m" />

<arg value="-J" />

<arg value="${outdir-gen}" />

<arg value="-S" />

<arg value="${resource-dir}" />

<arg value="-M" />

<arg value="${manifest-xml}" />

<arg value="-I" />

<arg value="${android-jar}" />
</exec>
</target>
<!-- 编译aidl文件 -->

<target
name="aidl"
depends="gen-R" >

<echo>
Compiling .aidl into java files...
</echo>

<apply
executable="${aidl}"
failonerror="true" >

<!-- 指定预处理文件 -->

<arg value="-p${framework-aidl}" />
<!-- aidl声明的目录 -->

<arg value="-I${srcdir}" />
<!-- 目标文件目录 -->

<arg value="-o${outdir-gen}" />
<!-- 指定哪些文件需要编译 -->

<fileset dir="${srcdir}" >

<include name="**/*.aidl" />
</fileset>
</apply>
</target>

<!-- 将工程中的java源文件编译成class文件 -->

<target
name="compile"
depends="aidl" >

<echo>
Compiling java source code...
</echo>

<javac
bootclasspath="${android-jar}"
destdir="${outdir-classes}"
encoding="utf-8"
srcdir="."
target="1.5" >

<classpath>

<fileset
dir="${external-lib}"
includes="*.jar" />

<filelist>

<file name="${android-maps-jar}" />
</filelist>
</classpath>
</javac>
</target>

<!-- 混淆代码 -->

<target
name="proguard"
depends="compile" >
<echo>
Proguad ....
</echo>
<jar
basedir="${outdir-classes}"
destfile="temp.jar" />

<java
failonerror="true"
fork="true"
jar="${proguard-home}/proguard.jar" >

<jvmarg value="-Dmaximum.inlined.code.length=32" />

<arg value="-injars temp.jar" />

<arg value="-outjars optimized.jar" />

<arg value="-libraryjars ${android-jar}" />

<arg value="-dontpreverify" />

<arg value="-dontoptimize" />

<arg value="-dontusemixedcaseclassnames" />

<arg value="-repackageclasses ''" />

<arg value="-allowaccessmodification" />

<!-- 混淆配置的引用 -->

<arg value="@proguard-project.txt"/>

</java>

<delete file="temp.jar" />

<delete dir="${outdir-classes}" />

<mkdir dir="${outdir-classes}" />

<unzip
dest="${outdir-classes}"
src="optimized.jar" />

<delete file="optimized.jar" />
</target>

<!-- 将.class文件转化成.dex文件 -->

<target
name="dex"
depends="proguard" >

<echo>
Converting compiled files and external libraries into a .dex file...
</echo>

<exec
executable="${dx}"
failonerror="true" >

<arg value="--dex" />
<!-- 输出文件 -->

<arg value="--output=${dex-ospath}" />
<!-- 要生成.dex文件的源classes和libraries -->

<arg value="${outdir-classes-ospath}" />

<arg value="${external-lib-ospath}" />
</exec>
</target>

<!-- 将资源文件放进输出目录 -->

<target name="package-res-and-assets" >

<echo>
Packaging resources and assets...
</echo>

<exec
executable="${aapt}"
failonerror="true" >

<arg value="package" />

<arg value="-f" />

<arg value="-M" />

<arg value="${manifest-xml}" />

<arg value="-S" />

<arg value="${resource-dir}" />

<arg value="-A" />

<arg value="${asset-dir}" />

<arg value="-I" />

<arg value="${android-jar}" />

<arg value="-F" />

<arg value="${resources-package}" />
</exec>
</target>

<!-- 打包成未签证的apk -->

<target
name="package"
depends="dex, package-res-and-assets" >

<echo>
Packaging unsigned apk for release...
</echo>

<exec
executable="${apkbuilder}"
failonerror="true" >

<arg value="${out-unsigned-package-ospath}" />

<arg value="-u" />

<arg value="-z" />

<arg value="${resources-package-ospath}" />

<arg value="-f" />

<arg value="${dex-ospath}" />

<arg value="-rf" />

<arg value="${srcdir-ospath}" />
</exec>

<echo>
It will need to be signed with jarsigner before being published.
</echo>
</target>

<!-- 对apk进行签证 -->

<target
name="jarsigner"
depends="package" >

<echo>
Packaging signed apk for release...
</echo>

<exec
executable="${jarsigner}"
failonerror="true" >

<arg value="-keystore" />

<arg value="${keystore-file}" />

<arg value="-storepass" />

<arg value="123456" />

<arg value="-keypass" />

<arg value="123456" />

<arg value="-signedjar" />

<arg value="${out-signed-package-ospath}" />

<arg value="${out-unsigned-package-ospath}" />
<!-- 不要忘了证书的别名 -->

<arg value="blockcheng" />
</exec>
</target>

<!-- 发布 -->

<target
name="release"
depends="jarsigner" >

<!-- 删除未签证apk -->

<echo>
delete unsigned apk
</echo>
<delete file="${out-unsigned-package-ospath}" />
<echo>
copy apk from ${out-signed-package-ospath} to D:/workspaceAndroid/Release/happyShopping.apk
</echo>
<copy
file="${out-signed-package-ospath}"
tofile="D:/workspaceAndroid/Release/happyShopping.apk" />
<echo>
clean the workspace bin folder....
</echo>
<delete dir="${outdir-classes}"/>
<delete file="${dex-ospath}" />
<delete file="${resources-package-ospath}" />
<delete file="${outdir-bin}" />
<echo>
</echo>
</target>

</project>

如果不需要混淆代码,去掉上面的 proguard相关的配置就可以了
五、配置proguard属性:

proguard-project.txt

# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html 
# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontskipnonpubliclibraryclasses
-dontpreverify

-libraryjars libs/android-support-v4.jar
-libraryjars libs/core.jar

-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-dontwarn android.support.v4.**

-keep class android.support.v4.app.** { *; }

-keep interface android.support.v4.app.** { *; }

-keep class com.actionbarsherlock.** { *; }

-keep interface com.actionbarsherlock.** { *; }

-keepattributes *Annotation*

-keep public class * extends android.app.Activity

-keep public class * extends android.support.v4.app.Fragment

-keep public class * extends android.support.v4.app.FragmentActivity

-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 * extends blockcheng.BssicAct

-keep public class * extends blockcheng.controller.BCFragment

-keep public class com.android.vending.licensing.ILicensingService

-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);
}

-keepclassmembers class * {
public <init>(org.json.JSONObject);
}

-keep public class blockcheng.R$*{
public static final int *;
}

-keep public class blockcheng.controller.BlockchengClass.JavaScriptInterface {
public <methods>;
}

-keepnames class blockcheng.controller.BlockchengClass$* {
public <fields>;
public <methods>;
}

-keepnames class blockcheng.controller.BlockchengClass$* {
public <fields>;
public void showContacts();
}

上面的配置中,blockcheng、BC等开头的类,都是被我替换的,不是真实的,具体的类包名和类名,以各人自己的为主。
注意,这个混淆中,开始几行配置很重要,网上很多同学问的ant、proguard相关的错误(什么找不到app.android.v4类等),都是因为缺少这几行导致,但没人回答,这里,我就直接给出了:

-libraryjars libs/android-support-v4.jar
-libraryjars libs/core.jar

-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-dontwarn android.support.v4.**

-keep class android.support.v4.app.** { *; }

-keep interface android.support.v4.app.** { *; }

-keep class com.actionbarsherlock.** { *; }

-keep interface com.actionbarsherlock.** { *; }

-keepattributes *Annotation*

-keep public class * extends android.app.Activity

-keep public class * extends android.support.v4.app.Fragment

-keep public class * extends android.support.v4.app.FragmentActivity

这个配置主要是针对 android-support.v4和库相关的,请需要的同学注意。

最后的几行配置,是因为我代码中调用了asset中js文件导致的,js相关的操作代码,是不可以混淆的,故需要避开。

六、运行ant命令,构建开始:

命令行输入类似: D:/Android/apache-ant-1.9.2/bin/ant.bat -buildfile D:/workspa
ceAndroid/naomiHappyShopping/build.xml

就可以完成代码混淆和apk输出:

.......
release:
[echo]
[echo]                 delete unsigned apk
[echo]
[delete] Deleting: D:\workspaceAndroid\naomiHappyShopping\bin\HappyShoppingAn
t-unsigned.apk
[echo]
[echo]                 copy apk from D:\workspaceAndroid\naomiHappyShopping
/bin/HappyShoppingAnt.apk to D:/workspaceAndroid/Release/happyShopping.apk
[echo]
[copy] Copying 1 file to D:\workspaceAndroid\Release
[echo]
[echo]                 clean the workspace bin folder....
[echo]
[delete] Deleting directory D:\workspaceAndroid\naomiHappyShopping\bin
[echo]
[echo]

BUILD SUCCESSFUL
Total time: 41 seconds
看看时间,是不是比手动方便多了啊,而且反编译一看,代码真的不能再读了。
另外注意:不同人的路径等配置,需要根据各人自己的来,不能直接拷贝引用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息