Android国际化之多语⾔实现
前阵⼦因为公司朝着国际市场的进军,上⾯要求做起多语⾔的切换(⽬前只要求中英双语),其中踩了不少的坑,来这边简单归纳⼀下。根据往常,我把本章节进⾏⼀下⽬录整理如下:
1、系统设置中Android 7.0 前后语⾔设置的区别与准备⼯作
2、Application与Activity两种配置修改⽅式
3、具体的实现
4、踩的坑
⽬前能想到的就这么⼏个,现在我们进⼊正⽂。
1、系统设置中Android 7.0 前后语⾔设置的区别与准备⼯作
我们先从系统设置来查看⼀下,语⾔切换的变化
7.0之前的语⾔设置界⾯图
7.0及其之后的语⾔设置界⾯图
可知,在7.0之前,是直接把你⼿机的语⾔库列表进⾏展⽰,然后在列表中进⾏选择。⽽7.0及其之后则是通过进⾏添加把语⾔库加载进来,⽽加载进来的⼀般的第⼀的就相当于是你的母语(譬如中⽂),第⼆的相当于是你的第⼆语⾔(譬如英⽂)。显⽰的也是根据第⼀条对应的语⾔库进⾏语⾔库填充。
准备⼯作⼤致可分为以下⼏个步骤:
1、添加多语⾔⽂件:在不同的 value ⽂件夹下(例如 value 、value-en、values-zh-rTW ⽂件夹)添加不同语⾔的 l ⽂件。根    1、添加多语⾔⽂件:
据我的项⽬需求,⽬前只需要中英,所以对应⽬录建设如下,如果需要其他语⾔,你可以⾃⼰进⾏创建。
res下多语⾔资源⽂件分布图
2、⽂件属性配置:的在l⾥⾯进⾏配置,加上该权限
2、⽂件属性配置:
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION"/>
允许⼀个程序修改当前设置,如本地化(Allowsan application to modify the current configuration, such as locale. )
如果采⽤Activity的策略,则需要在l⽂件⾥的每⼀个Activity进⾏配置,这个在下⽂会详细说。
3、代码⾥的基本逻辑:这⾥就很笼统,⼀般是选择的机制和其他辅助⼯具的前期准备。⽐如我是通过SharePreference进⾏记录⽤户选择    3、代码⾥的基本逻辑:
之类的。我个⼈是认为这属于准备⼯作,所以在这边说明⼀下。
2、Application与Activity两种配置修改⽅式
总的来说,我们多语⾔的切换⼤多都是基于value⽂件夹下的string⽂件进⾏配置和获取。这就引伸到,我们获取这个资源的context是属于Activity还是Application了。这⾥我们先说⼀下,实现的步骤:
1、Applic a tio n⽅式
android简单教程这种⽅式配置简单,因为⼀个app只有⼀个application,我们针对的⽬标也就只有这么⼀个类,⽽且避免了⼀些情况下,某些activity的特殊情况造成不统⼀。当然,采取这种⽅式会带来⼀些问题,在我遇到的这些问题中,对应的针对⽅法也有(可能不够优美,或者更好的⽅法我没发现)。这⾥我把⼤致步骤说⼀下,⽐较重要的代码进⾏张贴,详细的步骤可以去搜索⽹上的。
先在application类中重写配置修改回调⽅法如下:
@Override
public void onConfigurationChanged(Configuration newConfig) {
ContextWrapper warp = LanUtils.wrap(this, TargetLable());
}
上⾯对应的⽅法在这⾥⾯,⽽TargetLable()则是我记录的,已经切换的locale的记录对象,这个⼩伙伴们可以⾃⾏实现。下述⽅法因为还有其他地⽅⽤得到,所以我进⾏封装
warp设置封装图
当然,在application类的onCreat⽅法也需要进⾏初始化,本⼈采取的是这种⽅法。因为还有⼀个跟随系统的选项,因此在每次app启动创建的时候进⾏语⾔选择⼀次。⾄此,当你把⼯具类实现了,就可以实现多语⾔切换了,但是这只能修改以application对应的context进⾏资源索引的更新,⽽布局⾥的采取的还是以activity,这时候你需要去你的baseActivity⾥重写该⽅法:
@Override
protected void attachBaseContext(Context newBase) {
Context context = LanUtils.wrap(newBase, TargetLable());
super.attachBaseContext(context);
}
这样在每次activity获取基本上下⽂的时候,才能将activity的context进⾏配置更新。当然,这种⽅式需要reCreate对应的已存在的activity 才能够较好地实现⽬标状态。
2、Activity⽅式
这个⽅式最⼤的优点就是可以不进⾏activity的重建,⽽且实现也很简单,但是隐患也相对多。这⾥我们先介绍⼀个属性:
Configuration 这个类描述了设备的所有配置信息,这些配置信息会影响到应⽤程序检索的资源。包括了⽤户指定的选项(locale和scaling)也包括设备本⾝配置(例如input modes,screen size  and  screen orientation).可以在该类⾥查看所有影响Configuration Change 的属性。
横竖屏切换是我们最常见的影响配置变化的因素,还有很多其他影响配置的因素有语⾔的更改(例如中英⽂切换)、键盘的可⽤性(这个没理解)等
常见的引发Configuration Change的属性:
横竖屏切换:android:configChanges="orientation"
键盘可⽤性:android:configChanges="keyboardHidden"
屏幕⼤⼩变化:android:configChanges="screenSize"
语⾔的更改:android:configChanges="locale"
在程序运⾏时,如果发⽣Configuration Change会导致当前的Activity被销毁并重新创建,即先调⽤onDestroy紧接着调⽤onCreate()⽅法。重建的⽬的是为了让应⽤程序通过⾃动加载可替代资源来适应新的配置。
当我们没有配置的时候,上述的变化都会造成activity的重建。因此我们在每个activity都需要补上对应属性,如:
android:configChanges="orientation|screenSize|locale
locale"
配置完后,我们在activity就不需要重建(对应是否会重建需要针对具体属性和场景,请⾃⾏搜索其他情况,这⾥不详细说明),只⾛对应回调⽅
法即可(同理,可针对横竖屏切换等的场景)
配置回调⽅法⽹上截图
同样,在这种⽅式下就可以在语⾔切换的时候,传递activity的上下⽂context进⾏多语⾔配置更新。
3、两种⽅式的优缺点
从上头我们可以知道,application⽅式,⽬标单⼀,⽐较不会造成混乱,⽽且在l配置⽂件也是⽐较清晰的。⽽activity ⽅式,则是⽆需重建activity,⽽且配置步骤⼗分简单。然⽽⼆者的缺点也是不可忽视的:
application:
需要重建activity,造成损耗;
当你⽣命周期管理不够好的时候,很容易在切换语⾔造成异常(当然这个不是它的锅,说明你⾃⼰⽣命周期管理不善);
当横竖屏切换、webview相关问题的时候也会出现语⾔设置失效。
activity:
Google官⽅并不推荐为了某单⼀配置变化⽽阻⽌重建进⾏⾃我配置,理由有⼏个,有⽹友简单归纳⼏点:
1.  配置改变和资源调整的问题,因为⽤这个⽅法我们需要⾃⼰往onConfigurationChanged()⾥写代码,保证所⽤资源和设备的 当前配置⼀致,如果⼀个马虎程序很容易出现资源指定的bugs,原⽂:
Google engineers,however, discourage its use. The primary concern is that it requires youto handle d
evice configuration changes manually in code. Handling configuration changes requires you to take many additional steps to ensure that each and every string, layout, drawable, dimension, ains in sync with the device's current configuration, and if you aren't careful, your application can easily have a whole series of resource-specific bugs as a result.——Handling Configuration Changes With Fragments
2. there are other configuration changes that you cannot prevent from restarting your application.有些configuration
changes没法阻⽌应⽤重启。(是说的有些android:configChanges的属性值对避免重建⽆效?不知道理解是否正确)
3. 很多开发⼈员会错误指定android:configChanges="orientation"来防⽌activity被销毁或重建这种不可预知的情况。但是引起Configuration Changes的情况很多,不⽌是屏幕旋转。⽐如修改设备默认语⾔,修改设备默认字体⽐例等等都可会引起配置改变。这种⽅法只对当前设置的配置有效,除⾮在manifest⾥把所有配置都列全。
4. 当⽤户离开应⽤,在回到应⽤前被销毁的话,例如点击了屏幕的Home键或者有个电话打进来,⽤户很久之后才回到应⽤程序,但是在此之前系统因为资源紧张⽽销毁了应⽤进程,当⽤户返回还是要
重新创建activity,问题等于没解决。
综上,取⽤哪种⽅法可以根据你的需求所决定。
3、具体的实现
上⽂已经说了实现⽅式的不同与各⾃的⽅法,⾃然也需要对应的实现⽅式。先说明以下,由于本⼈的app主活动需要⼀直存在,所以⼀开始设

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。