安卓項目中加載網頁使用騰訊的TBS,X5內核一直還好用,發現部分用戶手機出現了偶爾閃退的情況。
研究後發現報錯信息:
Using WebView from more than one process at once with the same data directory is not supported.
完整信息:
報錯用戶設備爲9.0以上,原來是因爲在Android Pie 的行爲變更中,框架安全性變更中包含了 WebView 的行爲變更。
爲改善 Android 9 中的應用穩定性和數據完整性,應用無法再讓多個進程共用同一 WebView 數據目錄。
此類數據目錄一般存儲 Cookie、HTTP 緩存以及其他與網絡瀏覽有關的持久性和臨時性存儲。
在大多數情況下,您的應用只應在一個進程中使用 android.webkit 軟件包中的類,例如 WebView 和 CookieManager。
例如,您應該將所有使用 WebView 的 Activity 對象移入同一進程。
您可以通過在應用的其他進程中調用 disableWebView(),更嚴格地執行"僅限一個進程”規則。
該調用可防止 WebView 在這些其他進程中被錯誤地初始化,即使是從依賴內容庫進行的調用也能防止。
如果您的應用必須在多個進程中使用 WebView 的實例,則必須先利用 WebView.setDataDirectorySuffix() 函數爲每個進程指定唯一的數據目錄後綴,然後再在該進程中使用 WebView 的給定實例。
該函數會將每個進程的網絡數據放入其在應用數據目錄內自己的目錄中。
解決方式:
public class WebApplication extends Application {
private static final String PROCESS = "com.sunzn.core";
@Override
public void onCreate() {
super.onCreate();
initPieWebView();
}
private void initPieWebView() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
String processName = getProcessName(this);
if (!PROCESS.equals(processName)) {
WebView.setDataDirectorySuffix(getString(processName, "sunzn"));
}
}
}
public String getProcessName(Context context) {
if (context == null) return null;
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) {
if (processInfo.pid == android.os.Process.myPid()) {
return processInfo.processName;
}
}
return null;
}
public String getString(String s, String defValue) {
return isEmpty(s) ? defValue : s;
}
public boolean isEmpty(String s) {
return s == null || s.trim().length() == 0;
}
}
注:以上的方法,還沒有解決我遇到的問題,真的心痛,可能是我設置Activity的啓動模式,導致程序運行的進程不同。
最後先將targetSdkVersion設置爲27,暫時解決問題。