Android - 如何在构建时为动态源项目动态设置包名?

Jam*_*igh 15 ant android open-source

我正在开发一个开源项目.由于任何人都可以下载源代码并自行构建,我不想在任何地方对包名称进行硬编码- 包括目录结构.

ant用于建筑.显然我可以修改build.xml,但我相信这会被覆盖android update.无论使用什么都将致力于Git回购,它不应该太复杂.

目前,直接从Git仓库构建代码的过程非常简单.以下是该README文件的摘录:

$ cd ~/src/isokeys/IsoKeys
$ android list targets # I build against API level 10.
$ android update project --name IsoKeys --target 1 --path ./ # Only needed first time.
$ ant debug && adb -d install -r bin/IsoKeys-debug.apk
Run Code Online (Sandbox Code Playgroud)

对我来说,将包名放入其中是有意义的local.properties,因为这是.gitignore'd.由于程序包名称不会出现在其他任何位置,因此构建将失败而不执行此操作.所以需要至少增加一步README,但我希望将其保持在最低限度.

编辑:当然,另一个要求是差异是有意义的 - 如果你手动重命名包名称他们不会.

Mat*_*lfe 21

我做了类似的事情(但不是因为这个原因),需要在构建时更新清单.我完成这个的方法是制作第二个AndroidManifest并将其放在名为config的目录下.所以在config/AndroidManifest中你可以有这样的东西:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="@CONFIG.APP_PACKAGE_NAME@"
      android:versionCode="@CONFIG.APP_VERSION_CODE@"
      android:versionName="@CONFIG.APP_VERSION@">


<!-- EVERYTHING ELSE GOES HERE -->


</manifest>
Run Code Online (Sandbox Code Playgroud)

然后你可以使用常规的裸骨build.xml ant脚本,只需进行一些修改(不需要从android构建系统复制整个脚本,因为它们添加了一些钩子供你使用而无需重新发明轮子).默认情况下,构建脚本应该读取local.properties,但如果不添加(或取消注释)这样的行:

<property file="local.properties" />
Run Code Online (Sandbox Code Playgroud)

在构建脚本中,您应该看到一个名为"-pre-build"的任务,将其更改为:

<target name="-pre-build">
     <copy file="config/AndroidManifest.xml" todir="." overwrite="true" encoding="utf-8">
       <filterset>
          <filter token="CONFIG.APP_PACKAGE_NAME" value="${app.packagename}" />
          <filter token="CONFIG.APP_VERSION" value="${app.version}" />
          <filter token="CONFIG.APP_VERSION_CODE" value="${app.versioncode}" />
       </filterset>
     </copy>           
</target>
Run Code Online (Sandbox Code Playgroud)

然后你的local.properties文件你会把包名,版本名/代码这样:

app.version=1.0
app.versioncode=1
app.packagename=com.mypackage.name
Run Code Online (Sandbox Code Playgroud)

现在你只需要确保你的清单,你完全符合所有的活动/服务/广播监听器等..这意味着你总是指定完整的包的源代码.如果你想让你自己的源代码的包是动态的,你可以将每个类的前缀替换为每个类..但这看起来有些愚蠢......很容易将你的代码打包在你自己的包名下面可以通过在项目中包含源代码或jar来从任何项目中使用它.

- 更新 - 哦,还有另一件事可以通知用户他们必须定义包名称是使用build xml中的fail标记,如下所示:

<fail message="app.packagename is missing. This must be defined in your local.properties file" unless="app.packagename" />
Run Code Online (Sandbox Code Playgroud)

把它放在读取local.properties文件的行之后


Jam*_*igh 7

感谢Matt Wolfe的帮助,到目前为止,我已经对我的努力发表了部分答复.

我注意到默认准系统build.xml也会导入custom_rules.xml:

<import file="custom_rules.xml" optional="true" />
Run Code Online (Sandbox Code Playgroud)

所以我创建了这个文件并开始修修补补.这是我到目前为止所提出的:

<?xml version="1.0" encoding="UTF-8"?>
<project name="custom_rules" default="debug">
    <target name="-pre-build">
        <fail message="Please define app.packagename in your local.properties file." unless="app.packagename" />
        <taskdef resource="net/sf/antcontrib/antcontrib.properties">
            <classpath>
                <pathelement location="/usr/share/java/ant-contrib.jar"/>
            </classpath>
        </taskdef>
        <!-- How do I check for propertyregex?
        <fail message="Depends on ant-contrib's propertyregex for app.packagename.path." unless="propertyregex" />
        -->
        <propertyregex property="app.packagename.path"
            input="${app.packagename}/"
            regexp="\."
            replace="/"
            global="true"
        />
        <copy todir="build/" overwrite="true" encoding="utf-8">
            <fileset dir="./">
                <include name="AndroidManifest.xml" />
                <include name="res/**" />
                <include name="lib/**" />
            </fileset>
            <filterset>
                <filter token="CONFIG.APP_PACKAGE_NAME" value="${app.packagename}" />
            </filterset>
        </copy>
        <copy todir="build/src/${app.packagename.path}" overwrite="true" encoding="utf-8">
            <fileset dir="./src/isokeys/">
                <include name="**" />
            </fileset>
            <filterset>
                <filter token="CONFIG.APP_PACKAGE_NAME" value="${app.packagename}" />
            </filterset>
        </copy>
    </target>
    <target name="-pre-clean" description="Removes output files created by -pre-build.">
        <delete file="build/AndroidManifest.xml" verbose="${verbose}" />
        <delete dir="build/res/" verbose="${verbose}" />
        <delete dir="build/lib/" verbose="${verbose}" />
        <delete dir="build/src/" verbose="${verbose}" />
    </target>
    <!-- NOW CHANGE DIRECTORY TO build/ BEFORE HANDING BACK OVER TO build.xml!!! -->
</project>
Run Code Online (Sandbox Code Playgroud)

这设置了所有内容build/ (这有额外的好处,保持整洁和整洁),现在的目的是让sdk工具build.xml从这个build/目录运行.但是,我找不到任何方式cd.