3 回答

TA貢獻1856條經驗 獲得超17個贊
背景:
Android WebView是使用WebKit構建的。雖然它最初是AOSP的一部分,但從KitKat開始,便決定將其WebView拆分為一個名為Android System WebView的單獨組件。本質上,它是一個預裝有Android設備的Android系統應用。就像其他系統應用(例如Google Play服務和Play商店應用)一樣,它會定期更新。您可以在已安裝的系統應用程序列表中看到它:
Android系統WebView
Android 7.0的變化:
從Android N開始,Chrome應用將用于渲染WebView第三方Android應用中的任何/全部。在開箱即用的Android N手機中,根本沒有Android WebView System應用程序。在已收到Android N的OTA更新的設備中,Android系統WebView被禁用:
WebView已禁用
和
WebView已禁用
此外,已引入多語言環境支持,并且設備具有多種默認語言:
在此處輸入圖片說明
對于具有多種語言的應用程序,這具有重要的意義。如果您的應用包含WebView,則這些內容將使用Chrome應用呈現。由于Chrome 本身就是一個Android應用,因此以其自己的沙盒流程運行,因此不會綁定到您的應用設置的語言環境。取而代之的是,Chrome將還原為主要設備的語言環境。例如,假設您的應用語言環境設置為ar-AE,而設備的主要語言環境設置為en-US。在這種情況下,Activity包含的語言環境WebView將從ar-AE變為en-US,并且將顯示來自相應語言環境文件夾的字符串和資源。您可能會在Activity具有WebViews的那些s 上看到大量的LTR和RTL字符串/資源。
解決方案:
完整的解決方案包括兩個步驟:
步驟1:
首先,在每個Activity(或至少每個Activity具有的)中手動重置默認語言環境WebView。
public static void setLocale(Locale locale){
Context context = MyApplication.getInstance();
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
Locale.setDefault(locale);
configuration.setLocale(locale);
if (Build.VERSION.SDK_INT >= 25) {
context = context.getApplicationContext().createConfigurationContext(configuration);
context = context.createConfigurationContext(configuration);
}
context.getResources().updateConfiguration(configuration,
resources.getDisplayMetrics());
}
在調用之前調用上面的方法setContentView(...)在onCreate()所有的活動的方法。該locale參數應該是Locale您希望設置的默認值。例如,如果您希望將阿拉伯語/阿拉伯聯合酋長國設置為默認語言環境,則應傳遞new Locale("ar", "AE")?;蛘?,如果您希望設置默認語言環境(即Locale由操作系統自動設置的語言環境),則應通過Locale.US。
第2步:
此外,您需要添加以下代碼行:
new WebView(this).destroy();
在onCreate()您的Application類(如果有的話),和任何其他地方的用戶可以更改語言。這將處理在更改語言后重新啟動應用程序時可能發生的各種極端情況(您可能已經注意到其他語言的字符串,或者在更改語言后在Android 7.0 ++ 上Activities具有相反的對齊方式WebView)。
作為附錄,Chrome自定義標簽現在是呈現應用內網頁的首選方式。

TA貢獻1808條經驗 獲得超4個贊
您的代碼似乎正在為應用本身(MyApplication.getInstance())的配置中設置語言環境。但是,您需要在擴展活動的內容視圖之前更新活動上下文的配置。我發現修改應用程序的上下文是不夠的(事實證明,甚至沒有必要)。如果我不更新每個活動上下文,則行為在各個活動之間是不一致的。
我采用的方法是子類化AppCompatActivity(或者Activity,如果不使用兼容性庫,則使用子類化),然后從該子類派生我的所有活動類。這是我的代碼的簡化版本:
public class LocaleSensitiveActivity extends AppCompatActivity {
@Override protected void onCreate(Bundle savedInstanceState) {
Locale locale = ... // the locale to use for this activity
fixupLocale(this, locale);
super.onCreate(savedInstanceState);
...
}
static void fixupLocale(Context ctx, Locale newLocale) {
final Resources res = ctx.getResources();
final Configuration config = res.getConfiguration();
final Locale curLocale = getLocale(config);
if (!curLocale.equals(newLocale)) {
Locale.setDefault(newLocale);
final Configuration conf = new Configuration(config);
conf.setLocale(newLocale);
res.updateConfiguration(conf, res.getDisplayMetrics());
}
}
private static Locale getLocale(Configuration config) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return config.getLocales().get(0);
} else {
//noinspection deprecation
return config.locale;
}
}
}
然后,在調用使用上下文的任何方法(例如)之前,請確保先調用super.onCreate(savedInstanceState)每個子類的onCreate()方法。setContentView()
- 3 回答
- 0 關注
- 1352 瀏覽
添加回答
舉報