我有一个Android应用项目,分为免费版和付费版。这两个项目的所有共同点都存在于一个名为"core"的Android库项目中。然后我有实际的Android应用项目,包括付费和免费版本。
我使用Ant脚本来构建这两个apk。付费版本设置了一个属性,告诉"核心"项目付费版本正在构建。免费版本告诉核心项目正在构建免费版本。
在Google决定发布ADT 22之前,这种方法曾经非常有效。现在"核心"项目不再拾取这些构建属性。
我怀疑库项目现在是在一个单独的Ant构建环境/进程中构建的。
所以这里是我的问题:我如何定义一个应用程序项目的build.xml文件中引用的Android库项目的属性?如何将属性传递到这些库项目构建?
在SDK的build.xml文件中实际编译的库项目在哪里?我想那是我们调查的好地方。
感谢您的宝贵时间。
编辑澄清
你必须从Android SDK(参见SDK-Folder/tools/ant
)创建原始build.xml
文件的修改副本,并且在Google发布ADT更新时,通过合并差异(当然要保留自己的修改)使其保持最新状态。
build.xml
文件使用<subant>
任务构建库项目,它基本上启动一个单独的构建环境,不会自动看到调用范围的任何属性(这将是应用程序项目的构建环境)。
但是,在subant
标记中,您可以使用<propertyset>
标记将调用方作用域的属性导出到库的构建XML。在您的build.xml
副本中查找以下代码块,并按如下所示进行修改:
....
<echo level="info">Building Libraries with '${project.libraries.target}'...</echo>
<!-- no need to build the deps as we have already
the full list of libraries -->
<subant failonerror="true" buildpathref="project.library.folder.path" antfile="build.xml">
<!-- *** ADD THIS: *** -->
<propertyset id="project.library.buildargs">
<propertyref prefix="project.library.buildargs" />
</propertyset>
<target name="nodeps" />
<target name="${project.libraries.target}" />
<property name="emma.coverage.absolute.file" location="${out.absolute.dir}/coverage.em" />
</subant>
....
上面的例子使所有应用项目的build.xml
属性都以project.library.buildargs.
为前缀对所有引用的Android库构建脚本可见。
我发现为免费版本和付费版本提供不同值的另一种解决方案是使用[资源]。Android构建链允许应用程序项目覆盖共享库项目中设置的资源值。
例如,您可以在res/values
中的任何XML文件中使用布尔资源:
<bool name="paid_version">false</bool>
当然,付费版本在自己的res/values
子目录中有相同的资源,值为true
。
然后从Activity
子类或任何其他具有Context
的类中,您可以执行以下操作:
if (getResources().getBoolean(R.id.paid_version)) {
// Do the paid version code here
}
这样做的好处是很容易实现。缺点是,这是基于动态代码的运行时检查。这意味着当资源值设置为false
时,编译器或任何其他静态分析工具都无法优化代码。