我正在做一个开源项目。由于任何人都可以下载源代码并自己构建它,因此我不想在任何地方对包名称进行硬编码 - 包括目录结构。
我用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。由于包名称不会位于其他任何位置,因此如果不执行此操作,构建将失败。所以README
中至少需要 1 个额外的步骤,但我想将其保持在最低限度。
编辑:当然,另一个要求是差异有意义 - 如果您手动重命名包名称,则它们没有意义。
我做了类似的事情(但不是出于这个原因(,需要在构建时更新清单。我实现这一点的方法是制作第二个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>
然后,您只需进行一些修改即可使用常规的裸骨构建.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 标记,如下所示:
<fail message="app.packagename is missing. This must be defined in your local.properties file" unless="app.packagename" />
把它放在读取 local.properties 文件的行之后
感谢Matt Wolfe的帮助,到目前为止,我正在发布部分答案。
我注意到默认的准系统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
的方法。
最简单的方法可能是尽可能晚地替换包名称。 这样,您甚至不必触摸代码。有一篇很好的文章名为重命名Android Manifest package(http://www.piwai.info/renaming-android-manifest-package/(。总结:
-
您可以使用
aapt --rename-manifest-package
修改包名称 -
或者,如果您希望软件包名称替换成为 ant 构建过程的一部分,则可以覆盖
-package-resources
目标:- 从 SDK 的生成中复制
-package-resources
目标.xml - 添加
manifestpackage
参数
- 从 SDK 的生成中复制