Ant編譯android,並Proguard代碼混淆,v4混淆配置

   忙了三四周,總算把購開心的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 &apos;&apos;" />

            <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
看看時間,是否是比手動方便多了啊,並且反編譯一看,代碼真的不能再讀了。

另外注意:不一樣人的路徑等配置,須要根據各人本身的來,不能直接拷貝引用。

相關文章
相關標籤/搜索