通过不同的产品风味或调试版本更改字符串资源

13
假设我们有一个名为strings_test.xml的文件,其中存储着用于测试的字符串值,应该在调试版本中显示。当apk构建为发布版本时,所有值都应更改为空字符串,例如:<string name="test_some_card_text">@string/empty</string>。是否有可能实现这一点?提前感谢。
5个回答

25

是的,您可以在应用程序 gradle 的 buildTypes 中完成此操作。

 buildTypes {
        mybuild {
                 resValue "string", "test_some_card_text", '"test"'
                 resValue "string", "other_text", '"other"'
                }
         debug {
                 resValue "string", "test_some_card_text", '"test"'
                 resValue "string", "other_text", '"other"'
              }
          }

然后像这样访问它。

getApplicationContext().getResources().getString(R.string.test_some_card_text);
getApplicationContext().getResources().getString(R.string.other_text);

构建需要选择相应的 构建变体 并进行构建。


我是否能在我的strings.xml文件中使用它作为文档类型实体? - Syzygy
@Syzygy,您能否详细说明您的问题或提出一个新问题? - Madhukar Hebbar
2
Madhukar,我相信@Syzygy指的是部分答案在这里:https://dev59.com/bVUL5IYBdhLWcg3wDUW2#51310147。然而,我也遇到了使用flavors切换XML实体(用于字符串)的问题。 - dekaru
这个能否作为字符串资源在XML文件中访问? - vipin agrahari

4
是的,Gradle可以让你覆盖字符串。
在你的app/build.gradle文件中的buildTypes{}里添加以下代码:
debug { applicationIdSuffix "debug" }
这样会在main目录旁边创建一个名为"debug"的文件夹。如果没有,则需要手动创建一个。(我没有尝试过,但我知道这是可能的。)
然后,如果你的strings_test.xml在res/values目录下,那么就在debug/下创建类似的目录结构,并将带有调试特定字符串的strings_test.xml放在其中。这将显示在你的调试版本中。release/main/res/values下的内容将显示在发布版本中。
PS:你可以根据buildTypes和flavor覆盖所有的res和asset数据。但你不能覆盖Java文件,不过你可以添加它们。

4
作为@Aditya Naik所说,使用Flavors是可行的。官方文档表示:
BuildType -> Flavor -> main -> Dependencies。
这意味着,如果一个资源在Build Type和main中都声明了,那么将选择Build Type中的那个。
请注意,在合并的范围内,具有相同类型、名称但不同限定符的资源是分开处理的。
这意味着,如果src/main/res有
- res/layout/foo.xml - res/layout-land/foo.xml
而src/debug/res有
- res/layout/foo.xml
那么合并后的资源文件夹将包含来自src/debug/res的默认foo.xml,但来自src/main/res的横向版本。
要了解更多信息,请访问 Official doc - Resource Merging

1
创建apk后无法更改字符串值。但是您可以在创建apk后动态地将值分配给文本或edittext ...等。

是的,这是真的。但是覆盖每个TextView/EditText本身似乎有点不方便。我猜应该可以通过提供不同的构建版本来实现,但我还没有找到解决方案。 - Martin Pfeffer
你能告诉我为什么要更改字符串的值,这样我就可以给你一些想法。 - ManiTeja
当我测试我的应用程序时,我希望能够在GUI中插入一些虚拟数据(包括多行以及各种组合等),让我们称其为“压力测试布局” :) 但是如果这些测试资源在发布版本中被覆盖会很好。 - Martin Pfeffer
是的,但我们不能这样做。在数据库中创建一个带有名称和ID的表,并将所有值传递到数据库和GUI中。虽然有点冗长,但只需要一次处理。我曾经为我的一个GUI做过同样的事情。 - ManiTeja

0

对于那些寻找一种类似方法来应用于raw资源的人,我使用buildConfigField处理了它。

gradle
...
buildTypes {
    debug {
        ...

        buildConfigField "int", "shared_resource_name", 'R.raw.debug_resource_name'

        ...
    }
    prod {
        ...

        buildConfigField "int", "shared_resource_name", 'R.raw.prod_resource_name'

        ...
    }
}

注意引号。然后,在文件中的任何原来直接访问R.raw.resource_value的位置,将BuildConfig.shared_resource_name放置其中。

我认为这可以用于其他资源。


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