忙了三四周,總算把購開心的ios版(appStore搜「購開心」)成功翻譯成了android版,UI效果基本保持一致,上一張UI效果圖吧,很養眼的: javascript
還不錯吧,進入正題吧。 html
之前一直是讓我徒弟混淆和打包的,這個就剩下我一我的了,弄了一次,時間過久了,還太麻煩了,因而,我就研究了下ant打包,下面就簡單說下吧: java
首先,作任何開發前,確定是各類環境搭建和配置啊,ant的搭建很簡單: linux
1、安裝ant android
到官方主頁http://ant.apache.org下載新版(目前爲Ant-1.9.2)的ant,獲得的是一個apache-ant-1.8.1-bin.zip的壓縮包。將其解壓到你的硬盤上,例如:D:\Android\apache-ant-1.9.2 ios
2、配置環境變量 web
window中設置ant環境變量: shell
ANT_HOME D:/Android/apache-ant-1.9.2 apache
path D:/Android/apache-ant-1.9.2/bin json
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"
3、驗證ant
爲了驗證ant是否成功安裝,能夠進行以下操做:
依次選擇:開始->運行->cmd,輸入以下命令:ant
若是出現以下內容,說明安裝成功:
Buildfile: build.xml does not exist!
Build failed
固然,JAVA_HOME、ANDROID_SDK_HOME等的配置這裏就不說了
4、咱們就在項目中添加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相關的配置就能夠了
5、配置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相關的操做代碼,是不能夠混淆的,故須要避開。
6、運行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看看時間,是否是比手動方便多了啊,並且反編譯一看,代碼真的不能再讀了。
另外注意:不一樣人的路徑等配置,須要根據各人本身的來,不能直接拷貝引用。