基本需求:
android的国际化的开发需求有以下两种情况:
1.获取系统的语言和地址,也就是跟随系统语言。
2.在app应用内进行语言设置。

基本知识了解:

1.Android会根据系统的语言地区设置自动的去匹配的资源包,比如简体中文先从(/values-zh-rCN)再(/values-zh)然后在(/values)。如果只有中文和英文,可以配置一个(/values-en)做英文资源,然后用默认的(/values)做中文资源;
2.一般是在 Android src/main/res/ 目录下,建立对应语言文件夹,格式一般为:values-语言代号-地区代号,默认的资源是不包含语言代号和地区代号的;
3.配置选项包括语言代号和地区代号。表示中文和中国的配置选项是 zh-rCN(zh表示中文,CN表示中国)也表示简体中文,zh-rTW(zh表示中文,TW表示台湾)也表示繁体中文。表示英文和美国的配置选项是 en-rUS(en表示英文,US表示美国),英语(英国):values-en-rGB(en表示英文,GB表示英国)。同一语言代号可以有多个地区代号,用 r 表示区分;
4.注意:默认的(/values是必须存在的,否则不能通过编译)
5.注意:Resources都可以配置多语言如layout,string;

获取和设置语言代码:

获取语言和地区有三种方法:通过 Java 自带的接口来实现,即:Locale locale = Locale.getLocale();String language = locale.getLanguage();String country = locale.getCountry();通过 Configuration 来获取//方法1,该方法已废弃,如果在 API >= 17 的版本上使用Locale locale = context.getResources().getConfiguration().locale;//方法2,在 API >= 17 的版本上可以使用Locale locale = context.getResources().getConfiguration().getLocales().get(0);String language = locale.getLanguage();String country = locale.getCountry();其中, context.getResources() 也可以用 Resources.getSystem() 来代替,前者获取的是应用内部的语言和地区设置,后者获取的是系统的语言地区设置,默认情况下,前者跟随系统设置。

更改 App 的语言设置

通过上述分析,我们已经知道怎么获取系统和应用的语言地区设置了。接下来,我们来讲一下如何实现 Android App 的多语言切换。在前面我们已经使用到了 Configuration ,这个类保存了 Android 应用的所有设备信息,详见 Configuration。要实现应用的多语言切换,我们所要做的就是更新 Configuration 中关于语言地区的属性。

Resources resources = context.getResources();DisplayMetrics metrics = resources.getDisplayMetrics();Configuration configuration = resources.getConfiguration();//API >= 17 可以使用configuration.setLocale(locale);//该方法已经废弃,官方建议使用 Context.createConfigurationContext(Configuration)resources.updateConfiguration(configuration, metrics);

重新加载资源

看到这里,你是不是觉得就结束了?不,当然不是,更新 Configuration 之后,如果不重启 Activity,应用的资源就不会被重新加载。Intent intent = new Intent(this, MainActivity.class);//开始新的activity同时移除之前所有的activityintent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);startActivity(intent);

持久化存储设置

当应用被杀掉重启后,之前所有的设置都已经失效,应用的语言地区又变成了系统默认的,这是因为我们对应用所做的变更只是保存在内存中,当应用被杀掉,在内存中的数据也随之被释放,再次启动应用的时候,应用读取的是系统的 Configuration ,语言地区也随之变成系统默认的。
当应用需要保存用户更改的操作,就需要对用户的选择进行持久化,并在应用重启的时候,从配置中读取并应用该配置。

public class MyApplication extends Application {     @Override    public void onCreate() {        super.onCreate();        //一般在 Application 的 onCreate() 方法中更新 Configuration        LanguageUtil.changeAppLanguage(this, Locale.SIMPLIFIED_CHINESE, true);    }}LanguageUtil.java/*** 更改应用语言** @param context* @param locale 语言地区* @param persistence 是否持久化*/public static void changeAppLanguage(Context context, Locale locale,                                    boolean persistence) {   Resources resources = context.getResources();   DisplayMetrics metrics = resources.getDisplayMetrics();   Configuration configuration = resources.getConfiguration();   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {       configuration.setLocale(locale);   } else {       configuration.locale = locale;   }   resources.updateConfiguration(configuration, metrics);   if (persistence) {       saveLanguageSetting(context, locale);   }} private static void saveLanguageSetting(Context context, Locale locale) {   String name = context.getPackageName() + "_" + LANGUAGE;   SharedPreferences preferences =           context.getSharedPreferences(name, Context.MODE_PRIVATE);   preferences.edit().putString(LANGUAGE, locale.getLanguage()).apply();   preferences.edit().putString(COUNTRY, locale.getCountry()).apply();}这样,Android 应用内多语言切换基本完工。接下来,分享一下我在多语言切换过程中遇到的坑。

多语言切换过程中遇到的坑

1.以静态变量的方式,在 Application 初始化时初始化网络请求错误提示语,然后再系统中切换语言后,网络请求错误提示语未更新。解决办法:使用时直接通过 getString() 方法获取。
2.App 多语言切换设置持久化后,在应用启动时, Application 的 onCreate() 中也进行了多语言切换。然后去系统设置中切换语言,App 也会随之跟随系统语言。原因:在我们改变系统的语言时,应用的 Configuration 也随之跟随系统改变,而不是我们启动应用时的设置了解决办法:监听 Activity 的生命周期,在 Activty 的 onCreate() 中判断应用当前的语言设置是否与用户设置值相同,否则强制更新应用语言设置。因为,当系统切换语言选项的时候,系统会重启 Activity,就如前文所说,我们需要重启 Activity 才能实现资源的重新加载一样。这里也有三种方案:
    a.创建一个基类 BaseActivity ,在其 onCreate() 方法中做处理
    b.使用 ActivityLifecycleCallbacks ,在其回调 onActivityCreated() 中做处理

    c.防止activity重建,在MainActivity的清单文件中配置android:configChanges="locale|layoutDirection"(会员系统是用这个方法),在application里重写方法:onConfigurationChanged(),这样就直接执行此方法来修改语言啦。
对比一下,上述两种方案,第一种只能针对继承自 BaseActivity 的才有效,第二种则是监听所以 Activity 的生命周期。所以相对而言,第二种方案更好点。

/*** 判断是否与设定的语言相同.** @param context* @return*/public static boolean isSameWithSetting(Context context) {  Locale current = context.getResources().getConfiguration().locale;  return current.equals(getAppLocale(context));}public class App extends Application {    @Override    public void onCreate() {        super.onCreate();        LanguageUtil.init(this);        //注册Activity生命周期监听回调        registerActivityLifecycleCallbacks(callbacks);    }    ActivityLifecycleCallbacks callbacks = new ActivityLifecycleCallbacks() {        @Override        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {            //强制修改应用语言            if (!LanguageUtil.isSameWithSetting(activity)) {                LanguageUtil.changeAppLanguage(activity,                        LanguageUtil.getAppLocale(activity));            }        }        //Activity 其它生命周期的回调    };}对于在 AndroidManifest.xml 中配置 launchMode 为 singleInstance 的 Activity,使用Intent intent = new Intent(this, MainActivity.class);//开始新的activity同时移除之前所有的activityintent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);startActivity(intent);

资源文件不更新。原因:launchMode 为 singleInstance 的 Activity 与当前应用时不在同一个 Task 栈解决方法:将 launchMode 改为其它模式或者杀掉应用重新启动。

资源文件夹为 values-zh-rCN时,将应用 Locale 设置为 Locale.CHINESE 时,找不到对应的资源文件。原因:values-zh-rCN 对应的 Locale 为 Locale.SIMPLIFIED_CHINESE解决办法:将 Locale 设置为 Locale.SIMPLIFIED_CHINESE 或者将资源文件改为 values-zh这是踩得最惨的一个坑,浪费了大量时间,所以才会有开头 Android 应用资源国际化 那么一小节插曲。

app设置语言后切换到MainActivty界面会出现一个白屏界面闪一下。解决方法是:

在清单文件中给MainActivity增加一个主题在style.xml 增加主题代码:    

更多相关文章

  1. 分支和循环(二)(零基础学习C语言)
  2. Nginx系列教程(六)| 手把手教你搭建 LNMP 架构并部署天空网络电影
  3. Android是怎么给你自己的程序选择语言的
  4. Flutter:手拉手带你极速构建漂亮的跨平台(iOS/Android)移动应用
  5. 美军方拨款 提升Android系统安全性能
  6. Android(安卓)4.1果冻豆新特性详解
  7. Google推Android新开发语言Sky:流畅度 秒iOS
  8. Android之传感器系统(Gsensor) .
  9. StevGuo系列文章翻译之Android系统属性

随机推荐

  1. linux系统和android系统的区别
  2. Android面试题精选,自己收藏下
  3. androidstudio搭建flutter环境,遇到的问题
  4. Android中的soundpool小结
  5. Android开发学习:ImageView的scaletype属
  6. android调用Webservice方法
  7. eclipse导入已存在的android工程时遇到An
  8. android简易画图板与五子棋
  9. Android中LocationManager的简单使用,获
  10. Android Animation之frame animation