我正在尝试使用Android Build系统中的resConfig和resConfigs。
我的项目遇到了这两个选项的问题所以我用android studio开始了一个新的空白项目。我附上了我的build.gradle,我只添加了resConfigs" en"," fr"
下android {
defaultConfig {
...
resConfigs "en", "fr"
...
}
}
定义了2种基本口味
productFlavors {
fr {
resConfig "fr"
}
en {
resConfig "en"
}
}
然后我创建了一个2 strings.xml文件并翻译了hello_world默认标签
/src/main/res/values/strings.xml(默认)
/src/main/res/values-en/strings.xml
/src/main/res/values-fr/strings.xml
有了这个,我希望MyApplication / app / builds / intermediates / res / en / debug中只能看到3个值文件夹,因为我在resConfigs中定义只使用" en"和" fr"并过滤其他任何东西
/ values /
/ values-en /
/值-FR /
虽然所有语言值文件夹仍在那里,所以resConfigs没有明显过滤任何内容。
我还希望在运行enDebug flavor变量时从values-en看到标签hello_world,因为我指定了flavor en将使用resConfig" en"虽然当我运行测试应用程序时,我看到来自/values-fr/strings.xml的标签而不是/values-en/strings.xml,因为平板电脑上的语言被配置为法国加拿大
我是否误解了resConfig背后的目的?如果是这样,我应该如何强制只使用语言运行并且不依赖于操作系统区域设置?此解决方案必须与flavorDimensions兼容,因为我在尝试配置的真实应用程序中使用它们。
注意:我还提交了一个错误,因为我认为此resConfig行为确实存在问题https://code.google.com/p/android/issues/detail?id=180694
由于
答案 0 :(得分:9)
好吧,经过好几个小时之后,对于那些遇到同样问题的人来说,这就解决了我的问题。
事实证明,resConfig不适合我。我发现强制特定风味的语言环境的正确和唯一方法是这样的:
首先,确保您的所有活动都扩展了一个共同的活动,该活动将负责强制使用区域设置。 (我必须创建2,因为我有一些活动扩展了FragmentActivity和一些扩展Activity。我也不喜欢在Activities构造函数中这样做但是因为我必须在getResources上完成任何调用之前调用applyOverrideConfiguration,I需要在活动的onStart 之前调用它。
public class LocaleMainActivity extends Activity {
public LocaleMainActivity() {
ActivityUtils.forceLocale(this);
}
}
public class LocaleMainFragmentActivity extends FragmentActivity {
public LocaleMainFragmentActivity() {
ActivityUtils.forceLocale(this);
}
}
//Method from ActivityUtils
public static void forceLocale(ContextThemeWrapper contextThemeWrapper) {
Configuration configuration = new Configuration();
Locale defaultLocale = new Locale(BuildConfig.LOCALE);
configuration.locale = defaultLocale;
contextThemeWrapper.applyOverrideConfiguration(configuration);
}
接下来,您需要在build.gradle flavor中定义区域设置
productFlavors {
myFrenchFlavor {
buildConfigField "String", "LOCALE", "\"fr\""
}
myEnglishFlavor {
buildConfigField "String", "LOCALE", "\"en\""
}
}
我在API 19+上测试了该解决方案。在应用程序中更改语言时也可以使用。
备用解决方案(不适用于Android M + see android bug report )
这个解决方案在stackOverflow上广泛传播,但我在Android M上实现这个时遇到了障碍,所以请记住这一点。
在AndroidApplication的onCreate()中,您可以使用区域设置调用updateConfiguration。
Locale myLocale = new Locale(BuildConfig.LOCALE);
Resources res = getResources();
Configuration conf = res.getConfiguration();
conf.locale = myLocale;
res.updateConfiguration(conf, res.getDisplayMetrics());
如果你定义了onConfigurationChanged()
,你还需要重置它@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Configuration config = new Configuration(newConfig);
config.locale = new Locale(BuildConfig.LOCALE);
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
}
编辑:请注意,此applyOverrideConfiguration目前有副作用,此处说明Chromium webview does not seems to work with Android applyOverrideConfiguration。 Chromium团队目前正致力于此!
感谢。
答案 1 :(得分:1)
resConfig
不会覆盖resConfigs
的指定defaultConfig
,而只是将它们组合起来。因此,您最终将获得包含en
和 fr
资源的所有口味。
因此,为避免这种情况,您不应在resConfigs
中指定任何defaultConfig
,只需将其设置为特定的风格。
此外,应用程序将始终包含默认values
,这意味着如果您有英语字符串,fr
风格仍将显示在设置为任何非法语的设备上的英语内容区域设置。