Mac中用Ant实现Android的批量打包碰到的一些问题以及解决方法

来源:IT165收集  发布日期:2015-02-27 20:15:48

Hello!各位新年好!
昨天下午开始上班,开始整理以前的笔记,留个印记,以免遗忘,当然若能对别人有帮助也再好不过了,今日深圳天气好的不像话,阳光透过玻璃洒在脸上,舒爽!

首先打包需要准备的情况:

1,Ant和JDK得安装好了,Ant去官网下http://ant.apache.org/
测试java环境,在控制台输入java -version
返回java版本号则表示成功

java version '1.6.0_65'
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-466.1-11M4716)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-466.1, mixed mode)

测试ant安装成功了没有,在控制台输入ant回车如果显示如下则表示成功

Buildfile: build.xml does not exist!
Build failed

2,Android SDK下的 /sdk/tools/ant/build.xml这个文件得存在,如果不存在则是你的ADT可能不完善,最好是找别人把SDK下的ant这个文件传给你,或者自己重新下一个ADT
3,在/sdk/tools/lib下放一个ant-contrib-1.0b3.jar包,如果没有则去下载1.0b3
4,项目中放置第三方jar包的文件夹不能是lib以免冲突
5,在AndroidManifest.xml中application标签下添加一个用来识别渠道的标签,比如
<meta-data android:name='UMENG_CHANNEL' android:value=“channel' />

以上准备工作完成后,接下来按照步骤来一步一步实现批量打包:


通过终端(cmd)命令自动生成build.xml和local.properties两个文件,方法如下:
[sdk]/tools/android update project -p [project] -t [target]
例如:
/Users/hl/Develop/adt-l/sdk/tools/android update project -p /Users/hl/Documents/workspace/AA -t 19
其中[sdk]为SDK全路径,[project]为项目全路径,[target]为API版本。

注:如果提示 Error: Target id ‘19’ is not valid. Use ‘android list targets’ to get the target ids.
那么就执行一下 /Users/hl/Develop/adt-l/sdk/tools/android list target 这条命令
[sdk] list target
我的执行后返回是:

Available Android targets:
----------
id: 1 or 'android-8'
     Name: Android 2.2
     Type: Platform
     API level: 8
     Revision: 3
     Skins: HVGA, QVGA, WQVGA400, WQVGA432, WVGA800 (default), WVGA854
 Tag/ABIs : default/armeabi
----------
id: 2 or 'android-18'
     Name: Android 4.3.1
     Type: Platform
     API level: 18
     Revision: 3
     Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
 Tag/ABIs : default/armeabi-v7a
----------
id: 3 or 'android-19'
     Name: Android 4.4.2
     Type: Platform
     API level: 19
     Revision: 4
     Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
 Tag/ABIs : default/armeabi-v7a
----------
id: 4 or 'android-21'
     Name: Android 5.0.1
     Type: Platform
     API level: 21
     Revision: 2
     Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
 Tag/ABIs : no ABIs.
----------
id: 5 or 'Google Inc.:Google APIs:8'
     Name: Google APIs
     Type: Add-On
     Vendor: Google Inc.
     Revision: 2
     Description: Android + Google APIs
     Based on Android 2.2 (API level 8)
     Libraries:
      * com.google.android.maps (maps.jar)
          API for Google Maps
     Skins: HVGA, QVGA, WQVGA400, WQVGA432, WVGA800 (default), WVGA854
 Tag/ABIs : default/armeabi
----------
id: 6 or 'Google Inc.:Google APIs:18'
     Name: Google APIs
     Type: Add-On
     Vendor: Google Inc.
     Revision: 3
     Description: Android + Google APIs
     Based on Android 4.3.1 (API level 18)
     Libraries:
      * com.android.future.usb.accessory (usb.jar)
          API for USB Accessories
      * com.google.android.media.effects (effects.jar)
          Collection of video effects
      * com.google.android.maps (maps.jar)
          API for Google Maps
     Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in
 Tag/ABIs : default/armeabi-v7a

此时我们把id改为6就可以运行了,如下图

构建build

执行完成后,Refresh你的项目就会发现项目的根目录下多了两个文件:
build.xml和local.properties
其中local.properties的内容是:

# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.

# location of the SDK. This is only used by Ant
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=/Users/hl/Develop/adt-l/sdk

build.xml的内容如下`

<?xml version='1.0' encoding='UTF-8'?>
<project name='SplashAcivity' default='help'>


    <!-- The local.properties file is created and updated by the 'android' tool.
         It contains the path to the SDK. It should *NOT* be checked into
         Version Control Systems. -->
    <property file='local.properties' />

    <!-- The ant.properties file can be created by you. It is only edited by the
         'android' tool to add properties to it.
         This is the place to change some Ant specific build properties.
         Here are some properties you may want to change/update:

         source.dir
             The name of the source directory. Default is 'src'.
         out.dir
             The name of the output directory. Default is 'bin'.

         For other overridable properties, look at the beginning of the rules
         files in the SDK, at tools/ant/build.xml

         Properties related to the SDK location or the project target should
         be updated using the 'android' tool with the 'update' action.

         This file is an integral part of the build system for your
         application and should be checked into Version Control Systems.

         -->
    <property file='ant.properties' />

    <!-- if sdk.dir was not set from one of the property file, then
         get it from the ANDROID_HOME env var.
         This must be done before we load project.properties since
         the proguard config can use sdk.dir -->
    <property environment='env' />
    <condition property='sdk.dir' value='${env.ANDROID_HOME}'>
        <isset property='env.ANDROID_HOME' />
    </condition>

    <!-- The project.properties file is created and updated by the 'android'
         tool, as well as ADT.

         This contains project specific properties such as project target, and library
         dependencies. Lower level build properties are stored in ant.properties
         (or in .classpath for Eclipse projects).

         This file is an integral part of the build system for your
         application and should be checked into Version Control Systems. -->
    <loadproperties srcFile='project.properties' />

    <!-- quick check on sdk.dir -->
    <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 per project custom build rules if present at the root of the project.
        This is the place to put custom intermediary targets such as:
            -pre-build
            -pre-compile
            -post-compile (This is typically used for code obfuscation.
                           Compiled code location: ${out.classes.absolute.dir}
                           If this is not done in place, override ${out.dex.input.absolute.dir})
            -post-package
            -post-build
            -pre-clean
    -->
    <import file='custom_rules.xml' optional='true' />

    <!-- Import the actual build file.

         To customize existing targets, there are two options:
         - Customize only one target:
             - copy/paste the target into this file, *before* the
               <import> task.
             - customize it to your needs.
         - Customize the whole content of build.xml
             - copy/paste the content of the rules files (minus the top node)
               into this file, replacing the <import> task.
             - customize to your needs.

         ***********************
         ****** IMPORTANT ******
         ***********************
         In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
         in order to avoid having your file be overridden by tools such as 'android update project'
    -->
    <!-- version-tag: 1 -->
    <import file='${sdk.dir}/tools/ant/build.xml' />

</project>

手动为项目新建一个File,该文件名为:ant.properties
创建完成项目的目录结构如下图:

key.store=/Users/hl/Develop/tmacsky
key.alias=tmacsky
key.store.password=987884492
key.alias.password=987884492
market_channels=10035,10034,10001,10002
app_version=1.2

keystore为签名文件的全路径
key.alias为签名需要使用的私钥
key.store.password为私钥库的密码
key.alias.password为私钥的密码
market_channels为渠道集合
app_version为apk的版本(此字段可根据自己喜好编写)。


现在开始build.xml文件的配置:
1,修改build.xml的第二行,修改方法如下:
其中name为你项目的名称,default设置为release。
例:<project name='AA' default='release'>

2,循环替换AndroidManifest.xml中UMENG_CHANNEL的value值并进行自动签名打包,方法如下:

 <import file='${sdk.dir}/tools/ant/build.xml' />  
    <property name='out.unaligned.dir' value='/Users/hl/Desktop/AA_${app_version}/' />  
    <mkdir dir='${out.unaligned.dir}' />  
    <target name='modify_update_file'>  
        <echo>*********************** make channel ${channel}</echo>  

        <replaceregexp file='AndroidManifest.xml'  
            match='channel'  
            replace='${channel}'  
            byline='false'  
            encoding='utf-8'  
        />  
        <property name='out.unaligned.file' location='${out.unaligned.dir}/HelloWorld_${app_version}_${channel}_android.apk'/>  

    </target>  

    <target name='make_one_channels' depends='savemanifest,modify_update_file,release,replacemanifest,deletebin' description='description'>  
    </target>  

    <target name='replacemanifest'>  
        <echo>*********************** replacemanifest</echo>  
        <delete file='${basedir}AndroidManifest.xml'/>  
        <copy file='..	empuildMETA-INFAndroidManifest.xml' todir='${basedir}' encoding='utf-8'/>  
    </target>  

    <target name='savemanifest'>  
        <echo>*********************** savemanifest</echo>  
        <copy file='${basedir}AndroidManifest.xml' todir='..	empuildMETA-INF' encoding='utf-8' />  
    </target>  

    <target name='deletebin'>  
        <delete dir='${basedir}in' />  
    </target>  

    <taskdef name='foreach' classname='net.sf.antcontrib.logic.ForEach' classpath='/Users/hl/Develop/adt-l/sdk/tools/lib/ant-contrib-1.0b3.jar' />  
    <target name='make_channels'>  
        <foreach target='make_one_channels' list='${market_channels}' delimiter=',' param='channel'>  
        </foreach>  
    </target>  

out.unaligned.dir的value值为apk输出文件夹的绝对路径,文件夹采用HelloWorld结合app_version命名,app_version为ant.properties中的app_version

out.unaligned.file的location为apk最终的输出路径,apk命名采用HelloWorld加app_version加当前的channel加android方式

打包的过程

第125行make_channels的target是ant的入口,该target中使用foreach循环调用名为make_one_channels的target(第106行)并把market_channels集合中的每个值替换给channel

make_one_channels的target指定了每次打包的过程:
   savemanifest:打包前先将原始的AndroidManifest.xml复制到与项目同一层级目录下的temp下build下META-INF中
   modify_update_file:匹配到AndroidManifest.xml中的channel并将其替换
   release:自动编译加签名
    replacemanifest:删除AndroidManifest.xml,将temp/build/META-INF中的原始AndroidManifest.xml复制回项目根目录下
   deletebin:删除bin文件(注:这步很重要,否则只能打出一个渠道的APK,当时做这块的时候碰到的问题)
第124行taskdef标签下的classpath是ant-contrib-1.0b3.jar的绝对路径

至此所有配置全部弄好了


下面开始打包
1,打开终端找到你的项目目录,例如:cd /Users/hl/Documents/workspace/AA/
2,然后执行ant make_channels
* 如果报如下的错误则说明你的Android SDK有问题,首先/sdk/tools/ant/build.xml这个文件得存在,不存在则去重新下一个ADT,如果存在则看看是否是Android SDK的路径没设置好

Buildfile: /Users/hl/Documents/workspace/AA/build.xml
BUILD FAILED
/Users/hl/Documents/workspace/AA/build.xml:90: Cannot find /Users/hl/Develop/adt-l/sdk/tools/ant/build.xml imported from /Users/hl/Documents/workspace/AA/build.xml
当出现BUILD SUCCESSFUL代表打包成功!可以看到路径下生成了四个apk,
打包文件
我安装了其中的一个10034测试,安装后在友盟后台看到,显示出这个渠道,如下图:
友盟渠道

注意:
1,每次打包前一定要删除掉temp/build/META-INF中的AndroidManifest.xml,特别是在给不同项目做打包时
2,打包前请检查AndroidManifest.xml中qudao的value值是否为channel,特别是打包失败后再次重新打包的时候一定要将value值改为channel
3,如果打包时出现Cannot recover key错误导致BUILDFAILD的话,请检查ant.properties中key.alias.password的值后面是否有多余的空格!有的话请把空格删除掉!


在代码中获取渠道值,方法如下:

    public static String getAppChannel(Context context) {
        String channel = 'UMENG_CHANNEL';
        try {
            ApplicationInfo appInfo = context.getPackageManager()
                    .getApplicationInfo(context.getPackageName(),
                            PackageManager.GET_META_DATA);
            channel = appInfo.metaData.getString('UMENG_CHANNEL');
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }
        return channel;
    }

测试项目:https://github.com/tmacsky/AA
参考:http://www.eoeandroid.com/thread-323111-1-1.html
http://blog.csdn.net/ljb_blog/article/details/12709947
http://blog.csdn.net/ljb_blog/article/details/12709983

Tag标签: 中用   方法   问题  
  • 专题推荐

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规