Android 國際化之多語言實(shí)現(xiàn)

? ? 前陣子因?yàn)楣境鴩H市場的進(jìn)軍,上面要求做起多語言的切換(目前只要求中英雙語),其中踩了不少的坑要销,來這邊簡單歸納一下构回。根據(jù)往常,我把本章節(jié)進(jìn)行一下目錄整理如下:

? ? 1疏咐、系統(tǒng)設(shè)置中Android 7.0 前后語言設(shè)置的區(qū)別與準(zhǔn)備工作

????2纤掸、Application與Activity兩種配置修改方式

? ? 3、具體的實(shí)現(xiàn)

? ? 4浑塞、踩的坑

? ? 目前能想到的就這么幾個借跪,現(xiàn)在我們進(jìn)入正文。

1酌壕、系統(tǒng)設(shè)置中Android 7.0 前后語言設(shè)置的區(qū)別與準(zhǔn)備工作

? ? 我們先從系統(tǒng)設(shè)置來查看一下掏愁,語言切換的變化

7.0之前的語言設(shè)置界面圖
7.0及其之后的語言設(shè)置界面圖

? ? 可知,在7.0之前仅孩,是直接把你手機(jī)的語言庫列表進(jìn)行展示托猩,然后在列表中進(jìn)行選擇。而7.0及其之后則是通過進(jìn)行添加把語言庫加載進(jìn)來辽慕,而加載進(jìn)來的一般的第一的就相當(dāng)于是你的母語(譬如中文)京腥,第二的相當(dāng)于是你的第二語言(譬如英文)。顯示的也是根據(jù)第一條對應(yīng)的語言庫進(jìn)行語言庫填充溅蛉。

? ? 準(zhǔn)備工作大致可分為以下幾個步驟:

? ? 1公浪、添加多語言文件:在不同的 value 文件夾下(例如 value 他宛、value-en、values-zh-rTW 文件夾)添加不同語言的?string.xml?文件欠气。根據(jù)我的項(xiàng)目需求厅各,目前只需要中英,所以對應(yīng)目錄建設(shè)如下预柒,如果需要其他語言队塘,你可以自己進(jìn)行創(chuàng)建。

res下多語言資源文件分布圖

????2宜鸯、文件屬性配置:的在AndroidManifest.xml里面進(jìn)行配置憔古,加上該權(quán)限

???<uses-permission android:name="android.permission.CHANGE_CONFIGURATION"/>

????允許一個程序修改當(dāng)前設(shè)置,如本地化(Allowsan application to modify the current configuration, such as locale. )

? ? 如果采用Activity的策略淋袖,則需要在AndroidManifest.xml文件里的每一個Activity進(jìn)行配置鸿市,這個在下文會詳細(xì)說。

? ??3即碗、代碼里的基本邏輯:這里就很籠統(tǒng)焰情,一般是選擇的機(jī)制和其他輔助工具的前期準(zhǔn)備。比如我是通過SharePreference進(jìn)行記錄用戶選擇之類的剥懒。我個人是認(rèn)為這屬于準(zhǔn)備工作内舟,所以在這邊說明一下。

2初橘、Application與Activity兩種配置修改方式

? ? 總的來說谒获,我們多語言的切換大多都是基于value文件夾下的string文件進(jìn)行配置和獲取。這就引伸到壁却,我們獲取這個資源的context是屬于Activity還是Application了批狱。這里我們先說一下,實(shí)現(xiàn)的步驟:

????1展东、Application方式

? ? 這種方式配置簡單赔硫,因?yàn)橐粋€app只有一個application,我們針對的目標(biāo)也就只有這么一個類盐肃,而且避免了一些情況下爪膊,某些activity的特殊情況造成不統(tǒng)一。當(dāng)然砸王,采取這種方式會帶來一些問題推盛,在我遇到的這些問題中,對應(yīng)的針對方法也有(可能不夠優(yōu)美谦铃,或者更好的方法我沒發(fā)現(xiàn))耘成。這里我把大致步驟說一下,比較重要的代碼進(jìn)行張貼,詳細(xì)的步驟可以去搜索網(wǎng)上的瘪菌。

? ? 先在application類中重寫配置修改回調(diào)方法如下:

????@Override

????public void onConfigurationChanged(Configuration newConfig) {

????????ContextWrapper warp = LanUtils.wrap(this, LanUtils.getTargetLable());

????????super.onConfigurationChanged(warp.getApplicationContext().getResources().getConfiguration());

}

????上面對應(yīng)的方法在這里面撒会,而LanUtils.getTargetLable()則是我記錄的,已經(jīng)切換的locale的記錄對象师妙,這個小伙伴們可以自行實(shí)現(xiàn)诵肛。下述方法因?yàn)檫€有其他地方用得到,所以我進(jìn)行封裝

warp設(shè)置封裝圖

? ? 當(dāng)然默穴,在application類的onCreat方法也需要進(jìn)行初始化怔檩,本人采取的是這種方法。因?yàn)檫€有一個跟隨系統(tǒng)的選項(xiàng)蓄诽,因此在每次app啟動創(chuàng)建的時候進(jìn)行語言選擇一次珠洗。至此,當(dāng)你把工具類實(shí)現(xiàn)了若专,就可以實(shí)現(xiàn)多語言切換了,但是這只能修改以application對應(yīng)的context進(jìn)行資源索引的更新蝴猪,而布局里的采取的還是以activity调衰,這時候你需要去你的baseActivity里重寫該方法:

????@Override

????protected void attachBaseContext(Context newBase) {

????????Context context = LanUtils.wrap(newBase, LanUtils.getTargetLable());

????????super.attachBaseContext(context);

????}

????這樣在每次activity獲取基本上下文的時候,才能將activity的context進(jìn)行配置更新自阱。當(dāng)然嚎莉,這種方式需要reCreate對應(yīng)的已存在的activity才能夠較好地實(shí)現(xiàn)目標(biāo)狀態(tài)。

????2沛豌、Activity方式

? ? 這個方式最大的優(yōu)點(diǎn)就是可以不進(jìn)行activity的重建趋箩,而且實(shí)現(xiàn)也很簡單,但是隱患也相對多加派。這里我們先介紹一個屬性:

????Configuration?這個類描述了設(shè)備的所有配置信息叫确,這些配置信息會影響到應(yīng)用程序檢索的資源。包括了用戶指定的選項(xiàng)(locale和scaling)也包括設(shè)備本身配置(例如input modes芍锦,screen size ?and ?screen orientation).可以在該類里查看所有影響Configuration Change 的屬性竹勉。

????橫豎屏切換是我們最常見的影響配置變化的因素,還有很多其他影響配置的因素有語言的更改(例如中英文切換)娄琉、鍵盤的可用性(這個沒理解)等

????常見的引發(fā)Configuration Change的屬性:

????橫豎屏切換:android:configChanges="orientation"

????鍵盤可用性:android:configChanges="keyboardHidden"

????屏幕大小變化:android:configChanges="screenSize"

????語言的更改:android:configChanges="locale"

????在程序運(yùn)行時次乓,如果發(fā)生Configuration Change會導(dǎo)致當(dāng)前的Activity被銷毀并重新創(chuàng)建,即先調(diào)用onDestroy緊接著調(diào)用onCreate()方法孽水。重建的目的是為了讓應(yīng)用程序通過自動加載可替代資源來適應(yīng)新的配置票腰。

? ? 當(dāng)我們沒有配置的時候,上述的變化都會造成activity的重建女气。因此我們在每個activity都需要補(bǔ)上對應(yīng)屬性杏慰,如:

????android:configChanges="orientation|screenSize|locale"?

????配置完后,我們在activity就不需要重建(對應(yīng)是否會重建需要針對具體屬性和場景,請自行搜索其他情況逃默,這里不詳細(xì)說明)鹃愤,只走對應(yīng)回調(diào)方法即可(同理,可針對橫豎屏切換等的場景)

配置回調(diào)方法網(wǎng)上截圖

? ? 同樣完域,在這種方式下就可以在語言切換的時候软吐,傳遞activity的上下文context進(jìn)行多語言配置更新。

? ? 3吟税、兩種方式的優(yōu)缺點(diǎn)

? ? 從上頭我們可以知道凹耙,application方式,目標(biāo)單一肠仪,比較不會造成混亂肖抱,而且在AndroidManifest.xml配置文件也是比較清晰的。而activity方式异旧,則是無需重建activity意述,而且配置步驟十分簡單。然而二者的缺點(diǎn)也是不可忽視的:

? ? application:

????需要重建activity吮蛹,造成損耗荤崇;

????當(dāng)你生命周期管理不夠好的時候,很容易在切換語言造成異常(當(dāng)然這個不是它的鍋潮针,說明你自己生命周期管理不善)术荤;

? ? 當(dāng)橫豎屏切換、webview相關(guān)問題的時候也會出現(xiàn)語言設(shè)置失效每篷。

? ? activity:

????AndroidManifest.xml里需要對每個activity進(jìn)行相關(guān)屬性配置瓣戚,使得結(jié)構(gòu)遠(yuǎn)不如上一個清晰;

? ? Google官方并不推薦為了某單一配置變化而阻止重建進(jìn)行自我配置,理由有幾個焦读,有網(wǎng)友簡單歸納幾點(diǎn):

????1.??配置改變和資源調(diào)整的問題子库,因?yàn)橛眠@個方法我們需要自己往onConfigurationChanged()里寫代碼,保證所用資源和設(shè)備的 當(dāng)前配置一致矗晃,如果一個馬虎程序很容易出現(xiàn)資源指定的bugs刚照,原文:

????Google engineers,however, discourage its use. The primary concern is that it requires youto handle device 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, etc.remains 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沒法阻止應(yīng)用重啟。(是說的有些android:configChanges的屬性值對避免重建無效喧兄?不知道理解是否正確)

????3.?很多開發(fā)人員會錯誤指定android:configChanges="orientation"來防止activity被銷毀或重建這種不可預(yù)知的情況无畔。但是引起Configuration Changes的情況很多,不止是屏幕旋轉(zhuǎn)吠冤。比如修改設(shè)備默認(rèn)語言浑彰,修改設(shè)備默認(rèn)字體比例等等都可會引起配置改變。這種方法只對當(dāng)前設(shè)置的配置有效拯辙,除非在manifest里把所有配置都列全郭变。

????4.?當(dāng)用戶離開應(yīng)用颜价,在回到應(yīng)用前被銷毀的話,例如點(diǎn)擊了屏幕的Home鍵或者有個電話打進(jìn)來诉濒,用戶很久之后才回到應(yīng)用程序周伦,但是在此之前系統(tǒng)因?yàn)橘Y源緊張而銷毀了應(yīng)用進(jìn)程,當(dāng)用戶返回還是要重新創(chuàng)建activity未荒,問題等于沒解決专挪。

? ? 綜上,取用哪種方法可以根據(jù)你的需求所決定片排。

3寨腔、具體的實(shí)現(xiàn)

? ? 上文已經(jīng)說了實(shí)現(xiàn)方式的不同與各自的方法,自然也需要對應(yīng)的實(shí)現(xiàn)方式率寡。先說明以下迫卢,由于本人的app主活動需要一直存在,所以一開始設(shè)計的時候主活動的默認(rèn)運(yùn)行與界面復(fù)雜度都盡量降低冶共,因此重建的成本比較低乾蛤,采用了第一種方法,對應(yīng)的工具類多少也有點(diǎn)定制化了捅僵。

? ? 首先家卖,在application里onCreat進(jìn)行初始化:? ??

初始化代碼邏輯截圖

? ? ? ? 在我們每次進(jìn)行語言選擇的時候,就需要對本地的配置進(jìn)行語言選擇更新命咐,其中以7.0 為分界線,7.0之前與7.0+是存在差別的:

多語言配置代碼截圖

? ? 而跟隨系統(tǒng)的時候谐岁,就需要進(jìn)行設(shè)置監(jiān)聽:


????????<receiver

? ? ? ? ? ? android:name=".application.LocalChangeReceiver"

? ? ? ? ? ? android:enabled="true">

? ? ? ? ? ? <intent-filter>

? ? ? ? ? ? ? ? <action android:name="android.intent.action.LOCALE_CHANGED" />

? ? ? ? ? ? </intent-filter>

? ? ? ? </receiver>


public class LocalChangeReceiverextends BroadcastReceiver {

????@Override

? ? public void onReceive(Context context, Intent intent) {

????????if (intent.getAction().equals(Intent.ACTION_LOCALE_CHANGED)) {

????????????????//如果是跟隨系統(tǒng)醋奠,則進(jìn)行應(yīng)用重啟

? ? ? ? ? ? String userSelectLanguage = LocalModel.getLanguageSelect();

????????????if (LanUtils.DefaultLanguage.equals(userSelectLanguage)) {

????????????????exit...

? ? ? ? ? }else {

????????????LanUtils.languageSelect(userSelectLanguage,true);}}}

????}


? ? 對應(yīng)的邏輯可以自行完善

4、踩的坑

????第1個是橫豎屏切換伊佃,造成了多語言設(shè)置的失效

????由于項(xiàng)目采用了公司的前輩自己封裝的框架窜司,造成application類被其隱藏,只有對應(yīng)主要生命周期回調(diào)方法航揉,造成application的onConfigurationChanged無法重寫塞祈,所以在橫豎屏切換的時候發(fā)生該問題。

? ? 解決的方法很粗暴帅涂,由于就是在activity的每次onCreat的時候進(jìn)行context的語言與目標(biāo)語言是否一致议薪,如果一致就不操作,不一致就進(jìn)行語言選擇操作媳友。

?? ??第2個是WebView斯议,造成了多語言設(shè)置的失效

? ? 根據(jù)網(wǎng)上搜索,該問題是發(fā)生在Android N之后的版本醇锚,原因就是:

????webview 在Android N之后哼御,webview的相關(guān)類以及相關(guān)jar的修改

????Android N 之前:

? ? Android的WebView是使用webkit構(gòu)建的坯临。雖然它最初是AOSP的一部分,但是從KitKat開始恋昼,決定分離出WebView一個名為Android System WebView的組件看靠。它基本上是一個Android系統(tǒng)應(yīng)用程序,預(yù)裝了Android設(shè)備液肌。它會像其他系統(tǒng)應(yīng)用程序(如Google Play服務(wù)和Play商店應(yīng)用程序)一樣定期更新挟炬。您可以在已安裝的系統(tǒng)應(yīng)用列表中看到它:

????Android 7.0之后:

? ? Chrome應(yīng)用將用于呈現(xiàn)WebView第三方Android應(yīng)用中的任何/所有內(nèi)容。在具有Android N開箱即用的手機(jī)中矩屁,Android WebView系統(tǒng)應(yīng)用

????解決方法:

? ? 1辟宗、在對應(yīng)的application的onCreat里補(bǔ)充上:new WebView(this).destroy();? ??

????2、在所有Activity下重設(shè)語言吝秕。StackOverFlow的回答中說也可以只在含有WebView的Activity中重設(shè)泊脐。這里建議,還是全設(shè)置掉好一點(diǎn)烁峭。在你的BaseActivity中容客,并且在調(diào)用setContentView之前調(diào)用如下代碼設(shè)置你的Local。

? ? 不過本人切換語言有走activity重建约郁,所以缩挑,并沒有在每個activity進(jìn)行重設(shè)置。而是在對應(yīng)activity的初始化(onCreat)進(jìn)行語言判斷與設(shè)置鬓梅。為了在其前后創(chuàng)建的活動同樣進(jìn)行語言判斷與設(shè)置供置。

? ? 到這里,大致就把多語言設(shè)置進(jìn)行簡單的說明绽快。主要的步驟很簡單芥丧,但是里面的坑不少,本人遇到了相當(dāng)一部分坊罢,但是應(yīng)該還沒完全遇到续担,結(jié)合其他博客所闡述的情況,在這里進(jìn)行一些歸納與總結(jié)活孩,作為自己的筆記也希望能給你們提供參考物遇,如有疏漏或者錯誤,希望不吝指正憾儒,萬分感激??

? ? 注:本人所寫的工具類在如下網(wǎng)盤询兴,沒有完全獨(dú)立,簡單修改一下應(yīng)該是適用的起趾,希望能夠幫到你

? ? 鏈接:百度網(wǎng)盤共享地址? 密碼:d9nr

參考博文:

---------------------

作者:?回歸的阿廖? 來源:CSDN? ?題目:Android Configuration change引發(fā)的問題及解決方法

鏈接:https://blog.csdn.net/aliaooooo/article/details/23606179

---------------------

作者:拜天地??來源:CSDN? 題目:【安卓學(xué)習(xí)之常見問題】 多國語言橫豎屏?xí)r蕉朵,自動切換到默認(rèn)語言(android:configChanges的使用)

鏈接:https://blog.csdn.net/ljb568838953/article/details/77005347

---------------------

作者:火鳳燎原??來源:CSDN? ?題目:Android7(N)中webview導(dǎo)致應(yīng)用內(nèi)語言切換失效

鏈接:https://blog.csdn.net/ArimaKisho/article/details/79798752

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市阳掐,隨后出現(xiàn)的幾起案子始衅,更是在濱河造成了極大的恐慌冷蚂,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件汛闸,死亡現(xiàn)場離奇詭異蝙茶,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)诸老,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進(jìn)店門隆夯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人别伏,你說我怎么就攤上這事蹄衷。” “怎么了厘肮?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵愧口,是天一觀的道長。 經(jīng)常有香客問我类茂,道長耍属,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任巩检,我火速辦了婚禮厚骗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘兢哭。我一直安慰自己领舰,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布迟螺。 她就那樣靜靜地躺著冲秽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪煮仇。 梳的紋絲不亂的頭發(fā)上劳跃,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天谎仲,我揣著相機(jī)與錄音浙垫,去河邊找鬼。 笑死郑诺,一個胖子當(dāng)著我的面吹牛夹姥,可吹牛的內(nèi)容都是我干的辙诞。 我是一名探鬼主播辙售,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼飞涂,長吁一口氣:“原來是場噩夢啊……” “哼祈搜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起士八,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎婚度,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蝗茁,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡醋虏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了哮翘。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片颈嚼。...
    茶點(diǎn)故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡忍坷,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出柑肴,到底是詐尸還是另有隱情旬薯,我是刑警寧澤晰骑,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布绊序,位于F島的核電站,受9級特大地震影響抚官,放射性物質(zhì)發(fā)生泄漏阶捆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一倍奢、第九天 我趴在偏房一處隱蔽的房頂上張望垒棋。 院中可真熱鬧,春花似錦叼架、人聲如沸衣撬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽靠粪。三九已至毫蚓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間元潘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工牲距, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留钥庇,地道東北人。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓难述,卻偏偏與公主長得像吐句,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子嗦枢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容

  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程文虏,因...
    小菜c閱讀 6,404評論 0 17
  • 1.什么是Activity?問的不太多敏储,說點(diǎn)有深度的 四大組件之一,一般的,一個用戶交互界面對應(yīng)一個activit...
    JoonyLee閱讀 5,731評論 2 51
  • 哎呀呀 ,馬上就要面臨找工作了,媛媛心里緊張呀. 作為一個即將畢業(yè)的Android程序媛,開始面臨找工作了,...
    左神話閱讀 4,553評論 7 59
  • 介紹自己負(fù)責(zé)的部分已添,如何實(shí)現(xiàn)的。 自定義view viewGroup activity的啟動流程 事件傳遞及滑動沖...
    東經(jīng)315度閱讀 1,208評論 1 4
  • 今天畦幢,媽媽從集市上買回了一個小花盆,我把吃過的橘子里的核洗干凈宇葱,種在了小花盆里刊头,給它澆上水,放在了有陽光的地方原杂。我...
    48王子茉閱讀 124評論 0 0