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