【问题标题】:How do you manage multiple environments while developing Android apps?在开发 Android 应用程序时如何管理多个环境?
【发布时间】:2017-12-11 17:45:25
【问题描述】:

我们正在构建一个连接到云的 Android 应用。我们有一个用于 API 的测试 URL 和一个生产 URL。我们在开发时将应用程序连接到本地开发机器以与数据库通信,但发现每次我们为 Play 商店生成 APk 时,我们都会将全局 API URL 修改为生产 URL。

有没有更好的方法来管理 Android 环境?我们是否也可以有两个版本的应用程序(开发版)和 Play Store 版本?我无法拥有两个版本,因为这两个应用程序具有相同的签名。我们如何最好地管理这个?

【问题讨论】:

    标签: android


    【解决方案1】:

    现在有了 android studio 和 gradle 就很简单了。

    在您的应用 build.gradle 中编辑签名配置

    signingConfigs {
        debug {
            storeFile file("debug.keystore")
            storePassword "..."
            keyAlias "..."
            keyPassword "..."
        }
    
        prod {
            storeFile file("prod.keystore")
            storePassword "..."
            keyAlias "..."
            keyPassword "..."
        }
    
        dev {
            storeFile file("dev.keystore")
            storePassword "..."
            keyAlias "..."
            keyPassword "..."
        }
    }
    

    添加构建类型

    buildTypes {
    
        debug {
            buildConfigField 'String', 'BASE_URL', '"http://127.0.0.1:8080/"'
            ......
            signingConfig signingConfigs.debug
        }
    
        prod {
    
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    
            buildConfigField 'String', 'BASE_URL', '"http://prod.example.com"'
            ......
            signingConfig signingConfigs.prod
        }
    
    
        dev {
            buildConfigField 'String', 'BASE_URL', '"http://dev.example.com"'
            ......
            signingConfig signingConfigs.dev
        }
    }
    

    在您的代码中,获取此代码在 gradle 文件中配置的基本 url。

    public final static String BASE_URL = BuildConfig.BASE_URL;
    

    您还可以在 gradle 文件中放置不同的 KEY 或特定于构建类型的任何内容,并根据您正在运行的构建类型在代码中。

    甚至可以有不同的包名。

    productFlavors {
        my_prod {
            applicationId "com.example.packtwo"
        }
        my_dev {
            applicationId "com.example.packone"
        }
    }
    

    在最近的 gradle 配置中,指定包名有一些更新。如果使用 productFlavors,则必须添加 flavorDimensions。请参阅下面添加了 flavorDimensions 的代码

    flavorDimensions "pack"
    
    productFlavors {
        flavor_dev {
            applicationId 'com.example.packtwo'
            dimension "pack"
        }
    
        flavor_prod {
            applicationId 'com.example.packone'
            dimension "pack"
        }
    }
    

    这将为您提供有关产品风味和尺寸的更多详细信息

    https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html

    检查更多可能性...

    但如果您使用不同的风格,您可能必须处理清单合并等所有问题。

    【讨论】:

    • 我对这种方法最大的困扰是测试的 apk 不是部署的 apk。
    • 在 android studio 中,您可以作为生产构建或您创建的任何其他构建类型运行。您可以直接作为生产版本运行到您的设备。检查 android studio 左下角的 build variants 选项卡。
    • 更改构建变体 BuildConfig.BASE_URL 不导入我应该做什么
    • @MustafaShaikh 尝试 gradle 重建。我没有在较新的 android 环境中检查这些代码。我可以再检查一次,但需要 2-3 周后。
    • 是的,我已经将所有部分重建无效缓存,但在 android studio 4.0 中并没有修复
    【解决方案2】:

    这可以通过使用产品风味来实现。

    为了达到这个要求:

    首先,在你的项目的 app 文件夹下创建 2 个文件,分别是 development.propsproduction.props。或者您可以将这两个文件添加到 app 文件夹下的一个包中,例如 config。

    基本上,这两个文件包含键和值。这两个文件的密钥相同。但他们的价值观不同。这些文件包含一个键,例如“SERVER_URL”及其值。应该是这样写的:

    SERVER_URL=”Server_url_value”

    在这种情况下,只有 URL 不同。所以,我在 Props 文件中只添加了一个键值对。您可以添加更多。

    然后,在 app build.gradle 文件中创建 ProductFlavours,例如开发和生产。现在,访问包含 URL 的不同 props 文件,如下所示:

    productFlavors {
        development {
            getProps('./config/development.props').each { p ->
                buildConfigField 'String', p.key, p.value
            }
        }
        production {
            getProps('./config/production.props').each { p ->
                buildConfigField 'String', p.key, p.value
            }
        }
    }
    
    def getProps(path) {
        Properties props = new Properties()
        props.load(new FileInputStream(file(path)))
        return props
    }
    

    现在,对于每种风格,都有一个构建类型,并且这个 BuildType 被添加到 app build.gradle 中。例如,构建类型为 Debugrelease。我有两种口味,即开发和生产。因此,将使用风味和构建类型创建 gradle 任务,如下所示:

    assemble{flavourName}{BuildType}
    

    现在,您只需键入这些命令。它将生成所需的 APK 及其相应的 URL。命令是:

    ./gradlew assembleProductionRelease 将生成带有生产 URL 的发布版本。

    ./gradlew assembleDevelopmentDebug 将生成带有开发 URL 的调试版本。

    ./gradlew assembleProductionDebug 将使用生产 URL 生成调试版本。

    ./gradlew assembleDevelopmentRelease 将生成带有开发 URL 的发布版本。

    前三个 gradle 任务将非常有帮助。但最后一个任务将生成带有开发 URL 的发布版本。但这不推荐。所以,我们应该阻止开发者执行这个任务,即./gradlew assembleDevelopmentRelease

    现在要限制开发人员使用 Development URL 生成发布版本,请在您的应用 build.gradle 文件中添加此 sn-p:

    android.variantFilter { variant ->
        if(variant.buildType.name.equals('release')
                && variant.getFlavors().get(0).name.equals('development')) {
            variant.setIgnore(true);
        }
    }
    

    现在,如果我们尝试执行任务,即./gradlew DevelopmentRelease。 Gradle 将停止生成构建并抛出异常并会说:在根项目中找不到此任务 assembleDevelopmentRelease。

    【讨论】:

    • 这更适合作为对问题的评论。要将其格式化为答案,请解释感兴趣的知识以及它与提问者的情况有何关系。请保留您提供的参考资料,并添加任何其他对您的答案研究特别有帮助的参考资料。
    • 希望这对现在有帮助:)
    • 看起来好多了,但是,现在您将答案链接到仅链接的答案。 stackoverflow.com/a/43364551.
    【解决方案3】:

    至少使用 Ant 构建生产版本。这样,您可以在构建过程中设置某些配置值/标志。假设您有一个包含服务器 URL 的 config.xml 文件。您可以有不同的 Ant 构建目标,这些目标将更改 URL 以指向适当的服务器。查看this 教程。它准确地解释了这是如何完成的。

    【讨论】:

      【解决方案4】:

      如果您使用带有 gradle 的 android studio,我认为这被认为是最佳实践。

      你可能想看看这篇文章:http://tulipemoutarde.be/2013/10/06/gradle-build-variants-for-your-android-project.html

      也可以在 youtube 视频中找到:https://www.youtube.com/watch?v=7JDEK4wkN5I

      这也允许你为同一个应用拥有两个不同的包名。

      它使用 gradle 风格来实现您正在寻找的东西,并且非常容易实现。

      【讨论】:

      • 您不能添加到调试或发布构建类型而不是创建新的产品风格吗?
      【解决方案5】:

      您可以尝试 gradle buildTypeproductFlavor。它将允许您指定不同的环境变量,如 url、versionName 等和 applicationId,这将允许您进行 dev 和 prod 构建。 更多详情http://developer.android.com/tools/building/configuring-gradle.html

      【讨论】:

        【解决方案6】:

        我不知道在这种情况下最好的做法是什么,但我确实喜欢这样:

        您可以将您的应用设为 LIB 并创建 2 个应用:生产应用和测试应用。为这些应用程序导入您的库并构建它们的清单(它几乎是旧应用程序的复制粘贴)。然后替换每个应用程序中不同的 /res/ 文件...(您可以创建一个具有 URL 的 config.xml 文件)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-10-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-06-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多