我正在尝试使用Android Build系统中的resConfig和resConfigs。
Android Studio版本1.2.2
Gradle构建版本1.2.3
OSX 10.10.3
我的项目有这两个选项的问题,所以我用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”并过滤其他任何内容
/值/
/值恩/
/值-FR /
虽然,所有语言值文件夹仍然在那里,所以resConfigs没有明显过滤任何东西。
我还希望在运行enDebug flavorvariables时看到来自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
谢谢
好吧,经过几个小时,这里是我的问题的解决方案,最终遇到同样的问题。
事实certificateresConfig并不适合我。 我发现强制特定风味的语言环境的正确和唯一方法是这样的:
首先,确保您的所有活动都扩展了一个共同的活动,该活动将负责强制使用区域设置。 ( 我必须创建2,因为我有一些活动扩展FragmentActivity和一些扩展Activity。我也不喜欢在Activities构造函数中这样做但是因为我必须在getResources上完成任何调用之前调用applyOverrideConfiguration,我需要调用它在活动的开始之前 )。
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 + 请参阅android错误报告 )此解决方案在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似乎不适用于Android applyOverrideConfiguration 。 Chromium团队目前正致力于此!
谢谢。
resConfig不会覆盖defaultConfig的指定resConfigs ,而只是组合它们。 因此,您最终会得到包含en 和 fr资源的所有风格。
因此,为避免这种情况,您不应在defaultConfig指定任何resConfigs ,只需将其设置为特定的flavor。
此外,应用程序将始终包含默认values ,这意味着如果您有英语字符串, fr风格仍将显示在设置为任何非法语区域设置的设备上的英语内容。