【问题标题】:Multiple Android Application Package .apk files from single source code来自单一源代码的多个 Android 应用程序包 .apk 文件
【发布时间】:2011-11-22 09:28:26
【问题描述】:

我想要一个 Android 构建系统过程、命令行或 Eclipse,以从单个源代码库生成多个 .apk 文件。造成这种情况的一些常见原因 - 为具有不同要求的市场提供特定版本或免费和付费版本。

这个问题不是关于:

Google says“您可能需要为您打算发布的每个 APK 创建单独的 Android 项目,以便您可以适当地单独开发它们。您可以通过简单地复制现有项目并给它一个新名称来做到这一点。”然后他们好心地建议使用我理解的库。然后,他们顺便提到了我真正想要的:“一个可以根据构建配置输出不同资源的构建系统”

  • 我知道要在 JAVA 中完成条件编译,可以关闭“public static final”变量。 build.xml 中有一个example of tweaking 这样的值。请提供更完整的 Android Ant 构建配置示例或指向 OSS 项目的链接吗?顺便说一句,build.xml 是自动生成的,但我见过有人破解它,那它是如何工作的?

  • 如果在 Manifest.xml 中声明的包名称为 package="com.example.appname",如果需要发出多个不同名称的 .apk,是不是每个都需要一个单独的项目?

【问题讨论】:

  • 更好的答案是使用Gradle(见下面我的答案),Android Studio 正式支持。更加动态(可以随意添加其他应用程序)。没有变量指定正在为哪个应用程序编码,只有一个主要活动和一个AndroidManifest,应该是这样。

标签: android ant apk


【解决方案1】:

对此尖叫Gradle答案,如website中所述。它已正式内置于 Android Studio 中并受到鼓励。

太神奇了;我使用相同的源代码构建了 3 个独立的应用程序,具有自定义的文本和图形,没有任何特殊编码。只需要一些目录和Gradle 设置是必需的,我的其他帖子可以找到两者的答案。

它似乎很好地解释了所有基础知识。有关您的具体问题的答案,请查找Build Variants 下的Product Flavors 部分,其中描述了指定不同的风格。

正如该网站所解释的,此设计背后的部分目的是使其更具动态性,并且更轻松地允许使用基本相同的代码创建多个 APK,这听起来与您正在做的完全一样。

我可能没有解释得最好,但是那个网站做得很好。

【讨论】:

  • 这并没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方发表评论 - 您可以随时评论自己的帖子,一旦您有足够的reputation,您就可以comment on any post
  • 我对其进行了编辑以包含我之前打算包含的链接,它为用户提供了答案。
  • 现在看起来好多了,接近投票可能会被审稿人忽略,感谢改进。
【解决方案2】:

使用使用 graddle 作为构建系统的 Android Studio 构建变体可以轻松实现您的目标。

查看here了解更多详细信息。

【讨论】:

  • 我不得不同意 alijandro 的观点,因为上面的信息与四年前的 Android 构建环境的状态有关。一切都变了
  • 请将您的答案组织得更详细、更容易理解
【解决方案3】:

我遇到了同样的问题,但是将所有内容打包在一个带有标志的项目中对我来说不是解决方案。我写了一个例子,如何用 Maven 做到这一点:

How to create multiple Android apk files from one codebase organized by a Maven multi module project.

【讨论】:

【解决方案4】:

我认为最好的方式仍然是使用 libray 作为公共源代码,并使用两个不同的 Android 项目作为演示和生产包。这是因为在 Java 中,从 apk 到源代码的逆向工程非常简单。如果您将相同的源用于演示和生产,有人可能会破解您的 apk 下载演示包,提取 java 源并解锁源,更改变量以将其用作生产版本。 使用库可以将部分源码保留在生产包中,这样就无法将演示包用作生产包。

【讨论】:

    【解决方案5】:

    我的团队使用单个代码库 + 附加代码构建了 2 个不同的构建。 由于 android build 是基于 ant 脚本的,所以我使用 ant 脚本来完成这项工作。

    我使用xmltask 来操作manifest xml 文件和许多ant 任务(regexp、copy..)来编辑源代码。

    我准备了模板项目模板(包括 build.xml、default.properties、local.properties)并将新的源代码复制到这些项目模板中。复制完成后,并行运行 build.xml 以缩短构建时间。构建完成后,我得到多个 apk 文件。

    【讨论】:

      【解决方案6】:

      我正在从一个源代码树生成 2 个不同的 APK(演示和生产),并进行 3 处小修改:

      1) 我的 Application 类中有 public static final DEMO=true; //false;,根据我用来在演示/生产功能之间切换代码的​​值

      2) 有 2 个主要活动,例如:

      package mypackage;
      public class MyProduction extends Activity 
      {
          //blah-blah
      }
      
      package mypackage.demo;
      public class MyDemoActivity extends mypackage.MyProductionActivity
      {
          //blah-blah
      }
      

      3) 最后是 2 个单独的 AndroidManifest.xml 文件,它们根据演示/生产切换指向不同的启动器活动

      我在 2 个 APK 之间手动切换,但编写小型 ANT 任务以在它们之间自动切换并不困难

      【讨论】:

      • 两个清单文件的组合,定义了两个活动,太棒了。
      • @WalterKarshat 我知道,我很棒 :),虽然发明轮子真的很痛苦
      • 另外,Emmanuel 在答案中引用的文章似乎是说,更改清单包将导致 R.java 在新的(例如,演示)包中自动生成,扔掉你所有的现有的资源进口。你遇到过吗?如果是这样,它是如何解决的?
      • 问题:是否可以只更改清单元素中的包名称,然后只为清单中的每个活动提供完整路径,而根本不为演示创建新活动(而是依赖 DEMO=true 变量)?这似乎是伊曼纽尔回答引用的文章中采用的方法。我自己只是在学习这些东西,只是想指出上述文章似乎提出的问题。
      • 虽然这个答案在 2011 年可能是正确的,但现在已经过时了。更好的答案是使用 gradle product flavors,正如下面@craned 所回答的那样。
      【解决方案7】:

      This article 有一个很好的演练,其中包含如何在构建时修改配置文件的示例;请特别参阅 自定义构建使用 Java 配置文件 部分。请注意,关于 build.xmlant 的一些信息现在有点过时了。

      【讨论】:

      • 在我看来,完整的解决方案将涉及使用 Manifest 文件来控制包含的资源和包名称,以及使用构建系统有条件地编译 Java 并可能发出几个 .apk 文件。感谢您的链接!
      【解决方案8】:

      一种方法是维护两个单独的 AndroidManifest.xml,每个配置一个。您可以手动(复制)或自动(构建脚本)在两者之间来回切换。

      [edit] 这个人有系统做这种事情:http://blog.elsdoerfer.name/2010/04/29/android-build-multiple-versions-of-a-project/

      【讨论】:

      • 这是一个有用的提示,谢谢。请在构建脚本中举例说明如何做到这一点?
      • @Walter Karshat:我添加了一个指向我的答案的链接。我希望这是你需要的。
      • 感谢您的跟进,这是非常相关的信息。
      • @Walter Karshat:很高兴你喜欢它。别忘了把小绿色复选标记放在正确的位置! ;-)
      【解决方案9】:

      这是我们的情况:我们有一个代码库,我们从该代码库中为多个客户发布。他们每个人都对应用程序中的标题、背景和其他资源有不同的要求(更不用说包名了)。

      构建由 Ruby 脚本处理,该脚本修改 AndroidManifest,复制/替换客户端特定文件夹中的某些资源,然后转到 Android 的标准构建例程。构建完成后,脚本会将更改的文件重置为原始的“默认”状态。

      嗯...也许它不是最佳的,也绝对不是 Android 特定的,但我们就是这样做的。

      【讨论】:

      • 就地更改文件而不是改回文件对我来说有点“神奇”,但我很高兴它在您的安装中起作用。
      • 我会担心源代码和 Ruby 脚本之间的依赖关系。
      • 没有依赖,脚本不修改源代码,只修改资源。
      • 所以每个构建的应用程序都有相同的包名?
      • Android 和 Java 包几乎是独立的。在这种情况下,完整的活动名称如下所示:vendor.specific.package/com.company.product.MainActivity
      【解决方案10】:

      尽管您坚持这不是将共享代码打包到 Android 库中,但它确实是。您已经说过市场可能有不同的要求,或者有免费和付费版本。在每个示例中,您的两个最终输出 APK 具有不同的行为和/或资源。您可以将绝大多数代码放在一个共享的 Android 库中,然后在您的实际项目中保持差异。

      例如,我开发过需要同时发布到 Android Market 和 Amazon AppStore 的应用程序。 Amazon AppStore 要求,如果您链​​接到应用程序的市场页面,它必须是 Amazon 的(与 Android 市场页面相反)。您可以将 URL 存储在库中的资源中并在代码中使用,然后在 Amazon 项目中覆盖该资源以指向适当的 Amazon URL。

      如果你的结构正确,你可以在代码中做类似的事情,因为你的起点是你的应用程序对象,你可以继承它并用它做不同的事情。

      也就是说,如果你想添加一个 Ant 步骤来更改清单中的包名称,它只是 XML。作为预编译步骤进行修改应该不难。

      【讨论】:

      • +1 用于此用例的 android 库。这就是你想要的。
      • 我很喜欢将两个项目之间的通用代码推送到库(Android 或其他库)中的软件工程优势。
      • 库建议与我宁愿维护一个 Android 项目并有办法生成多个二进制目标的事实正交。谷歌明确谈到为同一个包生成多个 .apk 文件,这些文件在 SDK 和 GL 版本以及屏幕尺寸支持方面有所不同,但没有提供进一步的指导。我想听听那些已经实施过这种设置的人,或者可以指出已经实施过的项目。
      猜你喜欢
      • 2011-12-29
      • 1970-01-01
      • 2012-03-26
      • 2011-04-24
      • 2019-11-05
      • 1970-01-01
      • 2019-04-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多