【问题标题】:Android - testing vs. production versionAndroid - 测试版与生产版
【发布时间】:2011-09-15 08:25:10
【问题描述】:

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

谢谢

【问题讨论】:

    标签: android build


    【解决方案1】:

    我个人用这个来判断我是否处于调试模式:

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

    此代码基于android-manifest.xmlApplication 标记的debuggable 属性:

    • 如果此属性显式设置为truedebugMode 将设置为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 手机上单独运行(因此安装时不会覆盖)。
    • 我明白了。第二部分不是令人满意吗?
    • 感谢那里的第一个代码 sn-p!我正要问是否有一种方法可以根据我使用的是调试 APK 还是发布 APK 来更改资源,所以这应该对我有用。
    • 解决方案的第二部分很糟糕...维护 2 个单独的项目用于调试和发布版本...不不。例如,如果您需要 staging 版本,那么您有 3 个项目怎么办?
    • 以防万一有人需要在 Activity 之外或在一行中做同样的事情:boolean debuggable = (0 != (context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE));
    【解决方案2】:

    据我所知,您确实需要根据基本代码创建不同的应用程序。正如我所做的那样,完成此操作的一种方法是使用 Ant 脚本将整个项目源复制到另一个目录中,例如“测试”,并在这样做的同时替换(例如使用复制过滤)来自 XML 文件的某些值,就像来自 AndroidManifest.xml 一样。首先要替换的东西之一是应用程序包,它需要对每个应用程序都是唯一的。像Activities 这样的Java 类仍然可以驻留在原始包中,它们在AndroidManifest.xml 中的名称只需要是绝对的。一旦源被复制和过滤,您就可以使用来自主 build.xml 的 Ant 的 antcall 任务来构建定制的应用程序。所以最后,你可以说,例如:“ant -Denv=testing build”,你就有了一个可以安装在你的生产版本旁边的 APK。

    另一种选择是使用 Maven,它的 Android 插件支持项目覆盖。当然,您也可以使用库项目,请参阅:Android – multiple custom versions of the same app

    【讨论】:

    【解决方案3】:

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

    解决方案总结:

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

    解决方案说明。

    我个人使用 GIT,我相信这种方法也适用于其他 SCM 工具,但我没有对其进行测试。

    1. 我有 2 个存储库,一个用于开发,一个用于生产(您可以使用生产分支获得相同的效果,但我更喜欢不同的存储库,因为我不知道什么时候会有其他开发人员,而且我不知道不想让任何人(包括我)在没有备份的情况下对代码犯错。

    2. 您只需在每个仓库的清单文件中设置不同的包名,例如:

    3. 开发清单包名称 - dev.com.foo.appName
    4. 生产清单包名称 - com.foo.appName

    5. 对于每个活动,都需要使用绝对路径而不是相对方法。由于您没有真正的选择来更改您的包名称,如果您这样做,所有更改都在清单文件中,我认为这种方法几乎没有任何缺点。

    6. 然后,每次您将更改从开发人员存储库拉到生产存储库时,清单文件中的这些行都应该存在“冲突”,但实际上只会在第一次发生冲突您提取代码,然后合并工具会知道您在生产存储库中更喜欢哪一行。

    编辑

    使用这种方式一段时间后发现生成的R文件有问题。

    问题: 正在生成 R 文件,其包名称在包属性的清单文件中定义。然后找不到所有对R文件的引用(源文件的包名与manifest文件中的包名不同)。

    该问题有 3 个解决方案:

    善: 这个解决方案是最强大的,我建议你使用它(虽然没有自己尝试过)。此解决方案背后的想法是将 R 文件生成为与清单中所述不同的类名。在清单中,包将是 dev.com.foo.appName,但 R 文件将生成到 com.foo.appName。 为了实现它,请关注this answer

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

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

    【讨论】:

      【解决方案4】:

      我知道问题迟到了,但我会回答的。

      您可以使用 Gradle

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

      buildTypes {
          release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'      
          }   
      
          test {
            applicationIdSuffix ".test"
            versionNameSuffix "t"
            debuggable false
          }
      

      通过设置applicationIdSuffix 可以在一台设备上安装testrelease构建

      欲了解更多信息,请转到http://tools.android.com/tech-docs/new-build-system/user-guide

      【讨论】:

        猜你喜欢
        • 2020-03-06
        • 1970-01-01
        • 1970-01-01
        • 2014-08-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-28
        • 1970-01-01
        相关资源
        最近更新 更多