如何配置额外的属性以在 android 应用程序初始化时加载?

How to configure extra properties to load in a android app initialization?

我想设置一个变量 SERVER_URL 它将在环境 production, 测试, 开发.

我想做的事情:

@Override
protected void onCreate(Bundle bundle) {
    R.urls.SERVER_URL; // is it a valid approach using resources?
}

有没有办法在不更改代码的情况下切换环境(开发、生产、测试​​)?

实现此行为的最佳方法是什么?

有没有办法在 playstore my variable(SERVER_URL) 中配置它,或者我必须只在代码中实现?

你不能那样做。

通常为此,您会设置一个固定的后端 Web 服务,returns 您的 SERVER_URL,您将在启动时从您的应用程序中使用 API。

您可以使用不同的方法。理想情况下,您不应在运行时更改 URL 以最小化攻击面。这种方法可能会直接影响您应用的安全性。

如果您的目标是修改此 URL 而不触及代码,您可以在编译时绑定此值。您可以创建 application.properties 文件并针对不同的目标构建(开发、生产、测试​​)修改此文件。在您的代码中,您可以从属性文件中读取值而不是硬编码值。您可以将此文件放在 assets 文件夹中并应用必要的混淆。这样只有属性文件会发生变化,而您的应用程序的安全性保持不变。

另一种方法是在构建时提供此参数(当您执行 gradlew 命令时)。您可以添加将添加到 BuildConfig 的命令行参数。在您的代码中,您可以通过调用 BuildConfig.SERVER_URL 来简单地引用 URL。您可以按照此 来实现。

无论哪种情况,我都建议您在编译时绑定此值。

有两种方法可以做到:

1/ 按string 资源如你所愿

添加一个名为 secret_keys.xml 或任何名称的资源文件,以将其与其他资源文件分开。把你的钥匙,api端点放在这里作为普通的字符串资源,如果你不想弄乱本地化,记得添加translatable="false"

将该文件放在 app/debug/res/values/ 中。如果不存在,请创建一个新的 debug 文件夹。对 stagingrelease 执行相同操作,Android 将自动使用与构建类型同名的文件夹。

2/ 通过 properties 个文件

创建 3 个 .properties 文件并将您的密钥放入其中:

HOST="http://api.blablabla.com"
CLIENT_ID="hahaha"
CLIENT_SECRET="hehehe"

将其绑定到您应用程序中的 BuildConfig 变量 build.gradle,对其他构建类型执行相同操作:

def getPropertiesFile = { path ->
    Properties properties = new Properties()
    properties.load(new FileInputStream(file(path)))
    return properties
}

android {
    ...

    buildTypes {
        debug {
            ...

            getPropertiesFile('./config/development.properties').each { p ->
                buildConfigField 'String', p.key, p.value
            }
        }
        ...
    }
}

在您的应用中只需调用 BuildConfig.HOST 即可获取您想要的字符串

更新

忽略 .gitignore 中的这些配置文件:

app/config
secret_keys.xml