25

到目前为止,我一直专注于我的应用程序的编程,很少关注使构建过程更智能。因此,我一直在手动操作(“笨方法”),包括手动更新android:versionCodeandroid:versionName在 AndroidManifest.xml 中进行更新。

我现在想自动(即在构建或导出时):

  1. git从包含构建和版本代码的最新标签/分支中获取。
  2. 解析它们,以便我可以将它们分配给 AndroidManifest.xml 中的相应字段。
  3. 相应地修改 AndroidManifest.xml。
  4. 继续正常的构建过程(Eclipse+ADT,没有任何 Ant),就好像我手动完成了 1-2-3...

我发现了一些关于“预构建步骤”、builders 和build.xml的线索,但我不知道在哪里可以找到这些线索以及从哪里开始。

关于我可以在哪里找到有关该主题的更多信息的任何提示或指示?(一个分步教程将是理想的)

更新 1:我发现这个帖子暗示我:

  1. 右键单击项目,Properties > Builders
  2. 添加一个指向项目的 Ant 构建文件的构建器。
  3. 在 Java 构建器之前调用该构建器

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

更新 2:显然,可以将整个项目导出到 Ant 文件中。但我不确定那是我想要的。预构建步骤必须始终包含Ant 构建文件吗?

更新 3:构建一个 Ant 文件,仅用于预构建步骤,正确的方法吗?

4

4 回答 4

18

这是我用来为 AndroidManifest.xml 动态分配 versionCode 和 versionName 的方法。它仅在使用 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

于 2012-10-12T09:12:27.660 回答
3

您在设置预构建步骤方面走在了正确的轨道上,但是 ant 构建文件是您自己从头开始创建的。Eclipse 有一些它在外部使用的 ant 脚本来处理自动编译、打包和其他内容,但是您想创建一个单独的脚本来执行您想要的这些额外步骤。

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

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

ReplaceRegExp - 您将需要它来替换您放置在 AndroidManifest.xml 中的标记(可能是 @VERSIONCODE@ 和 @VERSIONNAME@ ),这些值最终应该被执行,并由 exec 返回的值。

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

于 2012-10-03T15:56:08.623 回答
2

您应该考虑使用maven-android构建。干净地构建项目后,使用版本更新插件自动增加版本号。

用 maven-android 编写构建脚本并不容易——但付出的努力是值得的,你应该考虑这个途径。

此外,本教程可能会派上用场(我将此处描述的技术的变体用于我自己的构建)

编辑(2014):

考虑迁移到 Android Studio 并使用 Gradle。请参阅:如何在 Android Gradle 中自动增加 versionCode

于 2012-09-24T05:52:55.897 回答
1

我设法实现这一点的方式:构建>执行shell(我们需要一些php代码来从数据库接收一些信息)并且字符串替换发生在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";
    }
?>
于 2012-09-17T11:33:18.517 回答