如何在Build期间自动修改Manifest中的versionName?

时间:2012-09-14 14:40:51

标签: android eclipse adt

到目前为止,我一直专注于应用程序的编程,并且很少关注使构建过程更加智能化。因此,我一直在手动(“愚蠢的方式”),包括在AndroidManifest.xml中手动更新android:versionCodeandroid:versionName

我现在要自动(即在构建或出口时):

  1. git获取包含构建和版本代码的最新标记/分支。
  2. 解析它们,以便我可以将它们分配到AndroidManifest.xml中的相应字段。
  3. 相应地修改AndroidManifest.xml。
  4. 继续正常的构建过程(Eclipse + ADT,没有任何Ant),好像我手工做了1-2-3 ......
  5. 我找到了一些关于“pre-build步骤”,构建者和build.xml的线索,但我不知道在哪里找到这些以及从哪里开始。

    有关该主题的更多信息,有哪些提示或指示? (一步一步的教程是理想的)

    更新1:我发现this thread建议我:

    1. 右键点击项目Properties > Builders
    2. 添加指向项目的Ant构建文件的构建器。
    3. 命令在Java构建器
    4. 之前调用该构建器

      很好,但哪里是项目的Ant构建文件?我在哪里找到它?

      更新2:显然,可以export the entire project into an Ant file。但我不确定这是我想要的。预建步骤必须始终包含Ant build file吗?

      更新3:正在构建一个Ant文件,only for the pre-build step,正确的方法?

4 个答案:

答案 0 :(得分:18)

这是我用来动态地将versionCode和versionName分配给AndroidManifest.xml的内容。它仅在使用ant构建时才有效,因此您必须先安装它。然后转到命令行中的项目目录并执行“android update project -p。”,这将创建用于使用ant构建的必要文件,如local.properties和build.xml。

然后打开 build.xml 并将其放在:

  <target name="-pre-build" depends="-custom-git-version,-custom-manifest-version">
  </target>

  <!-- Packages the application. -->
  <target name="-post-build">
    <antcall target="-custom-restore-manifest"/>

    <property name="suffix" value="${git.commits}-${git.version}.apk" />

    <exec executable="sed" inputstring="${out.final.file}" outputproperty="out.final.renamedfile">
      <arg value="s/\.apk/-${suffix}/" />
    </exec>

    <copy file="${out.final.file}" tofile="${out.final.renamedfile}" />
    <echo>Final file copied to: ${out.final.renamedfile}</echo>
  </target>  

  <!-- Custom targets -->
  <target name="-custom-git-version">
    <exec executable="sh" outputproperty="git.commits">
      <arg value="-c" />
      <arg value="git log --pretty=format:'' | wc -l" />
    </exec>
    <echo>git.commits: ${git.commits}</echo>
    <exec executable="git" outputproperty="git.version">
       <arg value="describe" />
       <arg value="--tags" />
       <arg value="--long" />
    </exec>
    <echo>git.version: ${git.version}</echo>
  </target>

  <target name="-custom-manifest-version">
     <echo>Creating backup of AndroidManifest.xml</echo>
     <copy file="AndroidManifest.xml" tofile="AndroidManifest.xml.antbak" preservelastmodified="true" />

     <replaceregexp
        file="AndroidManifest.xml"
        match='android:versionCode="(\d+)"'
        replace='android:versionCode="${git.commits}"' />

     <replaceregexp
        file="AndroidManifest.xml"
    match='android:versionName="(\d+\.\d+)\.\d+"'
    replace='android:versionName="\1.${git.commits}"' />
  </target>

  <target name="-custom-restore-manifest">
    <echo>Restoring backup of AndroidManifest.xml</echo>
    <move file="AndroidManifest.xml.antbak"
          tofile="AndroidManifest.xml"
          preservelastmodified="true"
          overwrite="true" />
  </target>

这个输出并不是你想要的,但它是一个开始 - 随意修改它:)结果就像“yourapp - .apk

使用此功能,您可以根据需要执行“ ant clean debug ”或“ ant clean release ”来构建应用程序。您还可以使用以下内容创建“ ant.properties ”文件:

key.store=keystore_file
key.store.password=some_password
key.alias=some_alias
key.alias.password=some_other_password

启用自动签名您的应用。

您还应该阅读:http://developer.android.com/tools/building/building-cmdline.html

答案 1 :(得分:3)

您正在设置预构建步骤,但是ant build构建文件是您从头开始创建的。 Eclipse有一些外部使用的ant脚本,可以处理自动编译,打包和填充,但你想创建一个单独的脚本来执行你想要的额外步骤。

所以,你将不得不学习一些关于ant脚本的知识来完成这项工作。您找到的其中一些链接为您提供了如何创建简单ant文件的基本概念。除此之外,您可能需要使用的一些ant任务是:

Exec - 你需要这个来执行你的git命令来获取你的版本信息。它有一个名为resultProperty的参数,您可以使用该参数将命令的输出存储到ant可以访问的属性中。 (或者您可以将命令输出到文件中,然后ant可以访问该文件。)

ReplaceRegExp - 您将需要这个替换令牌(可能是@ VERSIONCODE @和@ VERSIONNAME @)放置在您的AndroidManifest.xml中,其中值最终应该由exec返回的值。

您可能还希望在开始时执行exec任务,以将AndroidManifest.xml文件恢复到其原始状态(使用令牌),这样它就可以重复,无需手动清理。我会提供更多关于你需要在这些exec任务中运行的git命令的信息,但是我担心我的所有经验都是Subversion,所以你必须填补那里的空白。

答案 2 :(得分:2)

您应该考虑使用maven-android进行构建。完成项目构建后,使用version-update插件自动增加版本号。

使用maven-android编写构建脚本不能说是容易的 - 但是回报是值得的,你应该考虑这个途径。

此外,这个tutorial可能会派上用场(我使用此处描述的技术的变体用于我自己的构建)

EDIT(2014):

考虑迁移到Android Studio并使用Gradle。请参阅:How to autoincrement versionCode in Android Gradle

答案 3 :(得分:1)

我设法实现这一目标:构建&gt;执行shell(我们需要一些PHP代码来从db接收一些信息)并且字符串替换发生在php:

#!/usr/bin/php
<?php
    $filename = $WORKSPACE."/src/com/me/myapp/MyActivity.java";
    $file = @file_get_contents($filename);
    if($file) {
        $repl = preg_replace("OriginalString", "NewString", $file);
        file_put_contents($filename, $repl);
        echo "\n\nReplaced some stuff in $filename";
    }
?>