14

我正在开发一个开源项目。因为任何人都可以下载源代码并自己构建它,所以我不想在任何地方硬编码包名称- 包括目录结构。

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

对我来说,将包名放在 中是有意义的local.properties,因为这是.gitignore'd. 由于包名称不会出现在其他任何地方,因此如果不这样做,构建将失败。因此,至少需要多出 1 个步骤README,但我希望将其保持在最低限度。

编辑:当然,另一个要求是差异有意义 - 如果您手动重命名包名称,它们就没有意义。

4

3 回答 3

20

我做了类似的事情(但不是出于这个原因),需要在构建时更新清单。我实现这一点的方法是制作第二个 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>

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

<property file="local.properties" />

在您的构建脚本中,您应该看到一个名为“-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>

然后你的 local.properties 文件你会像这样放置包名、版本名/代码:

app.version=1.0
app.versioncode=1
app.packagename=com.mypackage.name

现在,您只需要确保在清单中完全限定所有活动/服务/广播侦听器等。这意味着您始终指定源代码的完整包。如果您希望您自己的源代码的包是动态的,您可以替换每个类的每个前缀。但这似乎有点愚蠢。将您的代码打包到您自己的包名下很容易,它们只需在项目中包含源代码或 jar,就可以从任何项目中使用它。

-- 更新 -- 哦,你可以做的另一件事来通知用户他们必须定义一个包名是在你的构建 xml 中使用失败标记,如下所示:

<fail message="app.packagename is missing. This must be defined in your local.properties file" unless="app.packagename" />

将其放在读取 local.properties 文件的行之后

于 2012-05-13T06:59:50.987 回答
7

感谢马特沃尔夫的帮助,到目前为止,我正在发布部分答案。

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

<import file="custom_rules.xml" optional="true" />

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

<?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>

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

于 2012-05-13T17:59:51.483 回答
1

最简单的方法可能是尽可能晚地替换包名称。这样,您甚至不必触摸您的代码。有一篇不错的文章,名为Renaming the Android Manifest package ( http://www.piwai.info/renaming-android-manifest-package/ )。概括:

  • 可以aapt --rename-manifest-package用来修改包名

  • 或者,如果您希望包名称替换成为 ant 构建过程的一部分,您可以覆盖-package-resources目标:

    • -package-resources从 SDK 的 build.xml复制目标
    • 添加manifestpackage参数
于 2014-04-08T12:45:45.443 回答