Android Ant之打包项目,增加zipalign

通过更新项目,让项目自动生成build.xml文件。
查看当前的已安装的sdk版本:  android list target

更新本项目,自动增加build.xml文件:  android update project -n HttpTestDowns -t 11 -p /Users/Ari/Desktop/LEE/HttpTestDown
-n 对应的是项目名称
-t 就是我们之前查询的SDK版本对应的ID,大家根据自己的项目版本做出选择即可,我这个是android-8 所以用ID 1 .
-p就是生成的路径

以下深蓝色需要改动。。。
命令后生成文件build.xml,自己创建一个名为custom_rules.xml 文件名是根据build.xml里面起的,先来说说build.xml

<?xml version="1.0" encoding="UTF-8"?>
<project name="WeiyuMusicSpread" default="help">
    <property file="ant.properties" />

    <property environment="env" />
    <condition property="sdk.dir" value="${env.ANDROID_HOME}">
        <isset property="env.ANDROID_HOME" />
    </condition>

    <loadproperties srcFile="project.properties" />

    <fail
            message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
            unless="sdk.dir"
    />

    <import file="custom_rules.xml" optional="true" />
    
    <import file="${sdk.dir}/tools/ant/build.xml" />
</project>


custom_rules.xml

<?xml version="1.0" encoding="UTF-8"?>
<project name="">
    
<!-- change this !!! 
set ANDROID_HOME env PATH to SDK Home -->
<property name="keystore" value="/Users/Ari/Downloads/weiyu_games/BubbleCombos/BubbleCom.keystore" />
<property name="keystore.password" value="123456" />
<property name="key.alias" value="BubbleCom.keystore" />
<property name="key.password" value="123456" />

<!-- //////////////////////////////////////////////////////////////////////////////////////// -->


<!-- build channel macro -->
<macrodef name="bc">  <!-- must set channel.name param -->
    <attribute name="channelName"/>
    
    <sequential>
    <echo message="*** CHANNEL NAME: @{channelName}"/>
          <!-- replace channel in AndroidManifest.xml -->
          <replaceregexp file="AndroidManifest.xml"
                   match="U0(\d)+"
                   replace="@{channelName}"
                   byline="true"/>

        <!-- build apk -->    
        <antcall target="clean"/>
        <antcall target="release"/>
    
        <!-- sign apk -->
        <sign-release/>
        <zipalign-release channelNum="@{channelName}"/>
        
        <mkdir dir="channels/@{channelName}"/>
        <move file="bin/${ant.project.name}-release-zipalign-@{channelName}.apk" todir="channels/@{channelName}/"/>
    </sequential>    
</macrodef>

<macrodef name="sign-release">
   <sequential> 
        <echo message ="signing the unsigned apk to final product apk bin/${ant.project.name}-release-unsigned.apk"/>
        <echo message ="jarsigner -keystore ${keystore} -storepass ${keystore.password} -keypass ${key.password} -signedjar bin/${ant.project.name}-release.apk bin/${ant.project.name}-release-unsigned.apk ${key.alias} "/>
        <exec executable="jarsigner">
            <arg value="-keystore" />
            <arg value="${keystore}" />
            <arg value="-storepass" />
            <arg value="${keystore.password}" />  <!-- 验证密钥完整性的口令,创建时建立的 -->
            <arg value="-keypass" />
            <arg value="${key.password}" /> <!-- 专用密钥的口令,就是key密码 -->
            <arg value="-signedjar" />
            <arg value="bin/${ant.project.name}-release.apk" /> <!-- 输出 -->
            <arg value="bin/${ant.project.name}-release-unsigned.apk" /> <!-- 未签名的apk -->
            <arg value="${key.alias}" /> <!-- 别名,创建时建立的 -->
        </exec>
    </sequential>        
</macrodef>

<macrodef name="zipalign-release">
    <attribute name="channelNum"/>
   <sequential> 
        <echo message ="zipalign the signed apk"/>
        <exec executable="zipalign">
            <arg value="-v" />
            <arg value="4" />
            <arg value="bin/${ant.project.name}-release.apk" /> <!-- signed apk -->
            <arg value="bin/${ant.project.name}-release-zipalign-@{channelNum}.apk" /> <!-- zipalign output -->
        </exec>
    </sequential>        
</macrodef>

<target name="buildchannels" >
    
    <bc channelName="U002"/>

</target>

</project>    

最后,终端下定位到项目的根目录,键入:ant buildchannels

 

==================================================================================

如果键入的友盟key没有规律的话,那就麻烦一点:
1. 首先创建一个AndroidManifest.xml的副本,名字暂且叫做AndroidManifest.tmp.xml
AndroidManifest.xml文件:深红色为改动部分

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ziipin.traffic"
    android:versionCode="9"
    android:versionName="1.6" >

    <uses-sdk
        android:minSdkVersion="7"
        android:targetSdkVersion="15" />
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.CALL_PHONE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.READ_LOGS"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    

    <application
        android:icon="@drawable/icon"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.Black.NoTitleBar">
        <activity
            android:name=".MainActivity" android:screenOrientation="nosensor">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".IllegalQueryActivity" android:screenOrientation="nosensor" android:launchMode="singleTask"/>
        <activity android:name=".QueryResultActivity" android:screenOrientation="nosensor"/>
        <activity android:name=".DailyDealsActivity" android:screenOrientation="nosensor"/>
        <activity android:name=".BuyHistoryActivity" android:screenOrientation="nosensor"/>
        
        <!-- push related -->
        <activity android:name="org.androidpn.client.NotificationDetailsActivity"
            android:label="Notification Details">
        </activity>
        <activity android:name="org.androidpn.client.NotificationSettingsActivity"
            android:label="Notification Settings">
        </activity>
        <service android:enabled="true"
            android:name="org.androidpn.client.NotificationService"
            android:label="NotificationService">
            <intent-filter>
                <action android:name="org.androidpn.client.NotificationService" />
            </intent-filter>
        </service>
                <service
            android:name="com.umeng.common.net.DownloadingService"
            android:exported="true"
            android:process=":DownloadingService" >
        </service>
        
        <meta-data android:value="4ff02c17527015106700001f" android:name="UMENG_APPKEY"></meta-data>
        <meta-data android:value="CHANNEL_NAME" android:name="UMENG_CHANNEL"/>
    </application>

</manifest>


2. custom.rules.xml, 红色为改动部分

<?xml version="1.0" encoding="UTF-8"?>
<project name="">
    
<!-- change this !!! 
set ANDROID_HOME env PATH to SDK HOme -->
<property name="keystore" value=""/Users/Ari/Downloads/TrraficKeyStone"" />
<property name="keystore.password" value="123456Zp" />
<property name="key.alias" value="trraficxinjiang" />
<property name="key.password" value="123456Zp" />

<!-- //////////////////////////////////////////////////////////////////////////////////////// -->

<target name="mytest" depends="release">
    <echo>signing the unsigned apk to final product apk ... </echo>
</target>


<!-- build channel macro -->
<macrodef name="bc">  <!-- must set channel.name param -->
    <attribute name="channelName"/>
    
    <sequential>
        <echo message="*** CHANNEL NAME: @{channelName}"/>
    
        <copy file="AndroidManifest.tmp.xml" tofile="AndroidManifest.xml" overwrite="true"/>
    
          <!-- replace channel in AndroidManifest.xml -->
          <replaceregexp file="AndroidManifest.xml"
                   match="CHANNEL_NAME"
                   replace="@{channelName}"
                   byline="true"/>
    
        <!-- build apk -->    
        <antcall target="clean"/>
        <antcall target="release"/>
    
        <!-- sign apk -->
        <sign-release/>
        
        <mkdir dir="channels/@{channelName}"/>
        <move file="bin/${ant.project.name}-release.apk" todir="channels/@{channelName}/"/>
    </sequential>    
</macrodef>

<macrodef name="sign-release">
   <sequential> 
        <echo message ="signing the unsigned apk to final product apk bin/${ant.project.name}-release-unsigned.apk"/>
        <echo message ="jarsigner -keystore ${keystore} -storepass ${keystore.password} -keypass ${key.password} -signedjar bin/${ant.project.name}-release.apk bin/${ant.project.name}-release-unsigned.apk ${key.alias} "/>
        <exec executable="jarsigner">
            <arg value="-keystore" />
            <arg value="${keystore}" />
            <arg value="-storepass" />
            <arg value="${keystore.password}" />  <!-- 验证密钥完整性的口令,创建时建立的 -->
            <arg value="-keypass" />
            <arg value="${key.password}" /> <!-- 专用密钥的口令,就是key密码 -->
            <arg value="-signedjar" />
            <arg value="bin/${ant.project.name}-release.apk" /> <!-- 输出 -->
            <arg value="bin/${ant.project.name}-release-unsigned.apk" /> <!-- 未签名的apk -->
            <arg value="${key.alias}" /> <!-- 别名,创建时建立的 -->
        </exec>
    </sequential>        
</macrodef>

<target name="buildchannels" >
    
    <bc channelName="UMENG_001"/>
     <bc channelName="UMENG_002"/>
     <!-- 
     <bc channelName="U003"/>
    <bc channelName="U004"/>
    <bc channelName="U005"/>
    <bc channelName="U006"/>
    <bc channelName="U007"/>
    <bc channelName="U008"/>
    <bc channelName="U009"/>
    <bc channelName="U010"/>
    <bc channelName="U011"/>
    <bc channelName="U012"/>
    <bc channelName="U013"/>
    <bc channelName="U014"/>
    <bc channelName="U015"/>
    <bc channelName="U016"/>
    <bc channelName="U017"/>
    <bc channelName="U018"/>
    <bc channelName="U019"/>
    <bc channelName="U020"/>
    <bc channelName="U021"/>
    <bc channelName="U022"/>
    <bc channelName="U023"/>
    <bc channelName="U024"/>
    <bc channelName="U025"/>
    <bc channelName="U026"/>
    <bc channelName="U027"/>
    <bc channelName="U028"/>
    <bc channelName="U029"/>
    <bc channelName="U030"/>
    <bc channelName="U031"/>
    <bc channelName="U032"/>
    <bc channelName="U033"/>
    <bc channelName="U034"/>
    <bc channelName="U035"/>
    <bc channelName="U036"/>
    <bc channelName="U037"/>
    <bc channelName="U038"/>
    <bc channelName="U039"/>
    <bc channelName="U040"/>
    <bc channelName="U041"/>
    <bc channelName="U042"/>
    <bc channelName="U043"/>
    <bc channelName="U044"/>
    <bc channelName="U045"/>
    <bc channelName="U046"/>
    <bc channelName="U047"/>
    <bc channelName="U048"/>
    <bc channelName="U049"/>
    <bc channelName="U050"/> -->
    
</target>

</project>    


3.原本的AndroidManifest.xml不需要改动。

这样做的原理是把AndroidManifest保留一个副本,单词执行完后,用原来的副本替换回来。

 

Ant打包出现的部分错误:
1. Invalid byte 3 of 3-byte UTF-8 sequence

解决办法一:

把所有汉字删除

解决办法二:

将<?xml version="1.0" encoding="UTF-8"?>中的UTF-8改成gbk 

 

 

 

 

posted on 2013-06-13 12:31  lee0oo0  阅读(6659)  评论(1编辑  收藏  举报