18

我有一个主要从 Android Market(现在是 Google Play)下载的 Android 应用程序。我们对源代码进行了一些调整,并提交给亚马逊应用商店,看看它得到了什么样的牵引力。我现在正在寻找一种可持续的方式来从通用代码库进行开发,然后进行构建,以便我可以提交给其中一个/两个。

亚马逊商店对可用 API 有一些限制,因此我想有条件地从该版本中删除/修改功能。由于 Java 不支持传统的条件编译,并且在 Eclipse 中有条件地包含文件似乎并不简单(甚至可能吗?),我想问问其他人正在做什么来解决这个问题。

诚然,我不是 Eclipse/Java 专家,所以请随意教我。

我在解决方案中寻找什么:

  • 使用 Eclipse 构建/调试。
  • 静态代码文件,带有环境/设置切换来控制要构建的内容。
  • 代码中没有重复的代码或条件逻辑来在运行时选择代码流

这是您专门为 Android 应用程序或其他基于 Java/Eclipse 的项目解决的问题吗?建议从哪里开始?

4

4 回答 4

10

在最新版本的 ADT(版本 17)中很容易做到这一点,尽管我确实发现它会使编译时间更长一些:

  1. 创建一个新的 Android 项目 ( proj-A )
  2. 转到Project->Properties,选择Android,然后选中“Is Library”
  3. 将所有常用代码移至proj-A,导入所有必要的库
  4. 为 Google Play 创建一个新的 Android 项目 ( proj-B )
  5. 转到 Project->Properties,选择 Android,然后将Proj-A添加到库中
  6. 对亚马逊版本重复 #4&5

如果您有一些应该为每个子项目设置不同的变量(即布尔 GOOGLE_PLAY_VERSION 以启用 Google Play 特定功能),您必须创建另一个项目来包含这些值,因为您不能让项目在一个圆形时尚。您可以通过添加以下步骤来解决此问题:

  1. 将所有子项目特定变量拉入一个或多个类,这些类仅用作这些变量的容器
  2. 创建一个“虚拟”Java 项目 ( dummy )
  3. 配置proj-A将新的 Source 链接添加到dummy的 bin 目录
  4. 在具有项目特定更改的每个子项目中添加配置类
  5. 利润!

请注意,dummy中的变量不应设置为 final,否则会覆盖子项目的设置。

这似乎是一项相当多的前期工作,但就版本控制而言,这对我来说效果很好。

编辑: 现在随着 Google 迁移到 Android Studio 和 Gradle,如果您要开始一个新项目,如果您想支持多个 APK,最好迁移到该版本,请参阅 Android 开发网站的Building Your Project with Gradle#Work with build variant。在决定之前评估该选项绝对没有坏处。

于 2012-04-02T06:02:27.067 回答
1

不幸的是,在运行时根据 C/C++ 条件编译中的内容更改流程是 Android 中的一种约定。

我们的应用程序必须为不同的 API 级别维护不同的行为,因此我们创建了一些应用程序级别的常量,这些常量基于我们可用的 API 级别信息进行静态初始化,并在整个代码中使用。这是 Google 在他们的示例中做事的方式(例如,请参阅ActionBarCompat兼容性库,尤其是此处使用的工厂方法)。

您可以创建一个 CustomBuild 接口,并在 AmazonBuild 和 GooglePlayBuild 中实现它,然后根据需要使用静态 getBuild() 方法来切换功能:

if(getBuild().shouldEnableFeatureX()){
    doStuff();
} else {
    doDifferentStuff();
}

然后,您只需担心在构建之间切换是工厂中的一两行代码,以及维护您希望在哪些版本中启用哪些内容。或者,您可以为每个构建包含不同版本的静态类 CustomBuild。

我将支持上述其他人的建议:切换到 Maven 之类的东西进行构建;设置好后,它应该会让您的生活更轻松。

我还要说,您应该按照上面的建议将应用程序的核心设为库,并拥有两个不同的模块(一个用于亚马逊,一个用于 Play 商店),它们依赖于该库,但每个模块仅包含一个自定义工厂文件(或者对于每种类型的构建都只是一个静态类,包含相同的“我应该做这件事吗?”方法......一旦你拥有了基础设施,这只是一个偏好问题)。

于 2012-04-02T18:18:35.690 回答
0

我还没有真正尝试过,但这是我考虑过的。

使用 Eclipse 链接到工作区外部目录中的文件的能力怎么样?

从一个 Eclipse 项目开始:为了争论,假设它是 Google Play 版本。

现在构建第二个项目,首先要求 Eclipse 链接(而不是复制)第一个项目中的源文件。

要开发第二个项目,请添加从原始项目子类化的类以实现您的修改。对于资源,您可以使用包含、属性覆盖和选择器的某种组合。

如果无法进行子类化或扩展,那么显然您必须复制原始源文件并对其进行破解。如果你真的是强迫症,你可能只需要维护一个补丁集,而不是一整套冗余的文件。

你怎么看,它会起作用吗?

于 2012-03-26T19:46:49.290 回答
-1

您可以在 Eclipse 中手动创建两个项目,它们指向相同的源文件夹,但具有不同的包含/排除过滤器和不同的目标目录。

然后两个 Ant 目标使用属性从 javac 文件集中切换排除文件就足以生成相应的 jar 文件。

目的是为每个目标获得一个干净的应用程序,而无需来自另一个目标的任何代码。

通过在属性文件或 XML 配置中作为可插入行为列出的特性,您的运行时将通过添加菜单条目来适应自身。

于 2012-03-27T21:44:14.757 回答