Android Ant之打包项目,增加zipalign

时间:2021-10-26 18:40:39

通过更新项目,让项目自动生成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="trrafic*" />
<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