安卓 - 测试版与生产版的区别

10

我面临问题。我需要以两种方式构建一个应用程序,第一种是用于开发(测试)的版本,第二种是生产版。有没有办法以编程方式实现?(使用某些构建引擎)我的意思是,如果可能的话,这两个应用程序都应该在同一设备上同时运行。这两个版本都是来自同一个Android项目的APK。

谢谢

4个回答

7

个人而言,我使用这个来确定我是否处于调试模式:

final PackageInfo pinfo = getPackageInfo(ctx);
final boolean debugMode = (pinfo.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;

这段代码基于android-manifest.xml文件中Application标记的debuggable属性:
  • 如果将该属性显式设置为true,则debugMode将被设置为true

  • 但是,如果将其显式设置为false或在xml中不存在(隐式值),则debugMode将被设置为false

这种方式无法在同一设备上同时运行两个应用程序,因为两个APK需要不同的包名称才能同时安装。因此,您需要构建两个Eclipse项目,每个项目都有自己的包名称(例如com.example.myapp.debugcom.example.myapp)并且可以使用一个公共库(com.example.myapp.common),其中包含几乎所有代码:
  • com.example.myapp.debugdebuggable标志设置为true

  • com.example.myappdebuggable标志设置为false


谢谢您的回答,但我现在正在寻找一些基于build.xml代码的解决方案。我想要构建开发者版本和发布(稳定)版本,同时调试我的应用程序。这两个版本都可以在同一台Android手机上分别运行(因此在安装时不会覆盖)。 - Waypoint
我明白了。第二部分不够满意吗? - Shlublu
谢谢你提供的第一段代码片段!我正想问是否有办法根据我使用的调试或发布版 APK 来更改资源,所以这对我很有用。 - Hal
2
解决方案的第二部分很糟糕...为调试和发布版本维护2个单独的项目...不行。如果需要举例进行分段,则有3个项目? - User
取决于您愿意做什么,正如帖子中所解释的那样。请记住,不同的项目可以共享相同的代码库。 - Shlublu
1
以防有人需要在Activity之外或单行中执行此操作:boolean debuggable = (0 != (context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE)); - Lisandro

1
据我所见,你确实需要从基本代码创建不同的应用程序。一种完成此任务的方法(就像我所做的那样)是使用Ant脚本将整个项目源代码复制到另一个目录(例如“testing”),并在此过程中替换某些XML文件中的特定值(例如来自AndroidManifest.xml)。其中首先要替换的是需要为每个应用程序唯一的应用程序包。Java类(如Activities)仍可以驻留在原始包中,它们在AndroidManifest.xml中的名称只需为绝对路径即可。一旦源代码已被复制和过滤,您可以使用主build.xml中的Ant的antcall任务构建定制的应用程序。因此,在最后,您可以说例如:“ant-Denv = testing build”,然后您就有了一个可与生产版本一起安装的APK。
另一种选择是使用支持项目覆盖的Maven Android插件。当然,您还可以使用库项目,请参见:Android - 同一应用程序的多个自定义版本

谢谢,我现在已经开始使用Ant了,但是如何用不同的部分替换字符串的一部分呢? - Waypoint
要替换文本文件中的内容,请参阅Ant的filtersets:http://ant.apache.org/manual/Types/filterset.html。要操作现有的XML文件,您可以使用来自http://www.oopsconsultancy.com/software/xmltask/的xmltask。 - jraanamo

0

我知道问题有点晚,但我会回答。

您可以使用Gradle

build.gradle文件中,您可以像这样定义单独的buildTypes

buildTypes {
    release {
      runProguard false
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'      
    }   

    test {
      applicationIdSuffix ".test"
      versionNameSuffix "t"
      debuggable false
    }

通过设置 applicationIdSuffix,可以在一个设备上安装测试发布版本的应用程序

有关更多信息,请访问http://tools.android.com/tech-docs/new-build-system/user-guide


0

我认为最简单的解决方案是使用某种源代码控制工具来实现。有很多好理由使用源代码控制,我相信大多数开发人员已经在使用它了。

解决方案概述:

  1. 拥有两个仓库(或分支),一个用于开发,一个用于生产。
  2. 为生产和开发应用程序选择不同的包名称。
  3. 在清单文件中使用绝对路径而不是相对路径。
  4. 只在第一次从开发环境拉取更改到生产环境时解决冲突。

解决方案描述:

我个人使用GIT,我相信这种方法也适用于其他源代码管理工具,但我没有测试过。

  1. 我有两个代码库,一个是开发用的,一个是发布用的(你也可以使用发布分支来达到相同的效果,但我更喜欢使用不同的代码库,因为我从不知道何时会有其他开发人员加入,我不想给任何人(包括我自己)犯下错误而没有备份代码的机会)。

  2. 你只需要在每个代码库的清单文件中设置不同的包名即可,例如:

  3. 开发用清单文件的包名 - dev.com.foo.appName
  4. 发布用清单文件的包名 - com.foo.appName

  5. 对于每个活动,需要使用绝对路径而不是相对路径。由于您几乎不可能更改软件包名称(如果真的更改了,所有更改都在清单文件中),我认为这种方法几乎没有什么缺点。

  6. 然后,每次你从开发代码库拉取代码到发布代码库时,清单文件中这些行应该会发生“冲突”,但实际上只有第一次拉取代码时才会有冲突,之后合并工具会知道你在发布代码库中喜欢哪一行。

编辑

使用这种方法一段时间后,我发现生成的 R 文件存在问题。

问题: R 文件的包名是在清单文件中的 package 属性中定义的。然后所有对 R 文件的引用都无法找到(源文件的包名与清单文件中声明的包名不同)。

有三种解决方案:

最佳方案: 这个解决方案是最健壮的,我建议你使用它(虽然我自己没有尝试过)。这个解决方案的思路是将 R 文件生成到一个与清单文件中声明的类名不同的类名中。在清单文件中,包名将是 dev.com.foo.appName,但 R 文件将生成到 com.foo.appName 中。 为了实现这一点,请参考 this answer

不好的: 不要使用这个解决方案,它真的很糟糕,我在这里声明,你可以避免它。在每个使用 R 文件的文件中,添加与清单中包名称相同的导入到 R 文件中。这是一个非常糟糕的解决方案,因为你将输入大量不相关的代码,你需要在生产环境中进行更改,并且对于每个新类,你都需要记住添加它。

还有更糟的: 最好不要使用这个解决方案,因为它是一种hack。此解决方案仅适用于资源不会经常更改的成熟应用程序。每当更改资源时,R文件将被重新生成,然后生成到清单中的包名称。你所需要做的就是将包名称(在清单中)更改为生产环境中的名称,清理项目,再次构建,并将包名称改回开发环境。然后Eclipse会询问是否更改配置,你选择不更改。这样,将存在两个R文件,一个带有开发包名称,一个带有生产包名称。由于成熟的应用程序中资源变化不多,你只需偶尔这样做一次。你将无法忘记它,因为如果你更改了资源,你将开始看到奇怪的bug。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接