年前遇到的這個問題霞势,今天年后第一天上班,在驗證別的問題的時候突然想到年前解決的這個問題厅贪,一時竟想不起當(dāng)時怎么解決的了泣崩,翻看代碼思考了一會兒才想起來睬愤,特在此記錄下劲蜻。
統(tǒng)計到的錯誤日志如下:
Process Name: 'com.xxxx.xxx’
Thread Name: 'main'
Back traces starts.
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xxxx.xxxx/com.xuetian.player.player.live.LivePlayDocActivity}: android.view.InflateException: Binary XML file line #7 in com.xxx.xxx:layout/intro_layout: Binary XML file line #7 in com.xxx.xxx:layout/intro_layout: Error inflating class com.xuetian.common.ui.lib.widget.LollipopFixedWebView
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3504)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3643)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:140)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:100)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2229)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:238)
at android.app.ActivityThread.main(ActivityThread.java:7798)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:512)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:995)
Caused by: android.view.InflateException: Binary XML file line #7 in com.xxx.xxx:layout/intro_layout: Binary XML file line #7 in com.xxx.xxx:layout/intro_layout: Error inflating class com.xuetian.common.ui.lib.widget.LollipopFixedWebView
Caused by: android.view.InflateException: Binary XML file line #7 in com.xxx.xxx:layout/intro_layout: Error inflating class com.xuetian.common.ui.lib.widget.LollipopFixedWebView
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
at android.view.LayoutInflater.createView(LayoutInflater.java:855)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:1008)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:963)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1125)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1086)
at android.view.LayoutInflater.inflate(LayoutInflater.java:682)
at android.view.LayoutInflater.inflate(LayoutInflater.java:534)
at com.xuetian.player.player.live.LiveIntroComponent.initIntroView(LiveIntroComponent.java:38)
at com.xuetian.player.player.live.LiveIntroComponent.<init>(LiveIntroComponent.java:28)
at com.xuetian.player.player.live.LivePlayDocActivity.initIntroLayout(LivePlayDocActivity.java:699)
at com.xuetian.player.player.live.LivePlayDocActivity.initComponents(LivePlayDocActivity.java:678)
at com.xuetian.player.player.live.LivePlayDocActivity.initViewPager(LivePlayDocActivity.java:564)
at com.xuetian.player.player.live.LivePlayDocActivity.onCreate(LivePlayDocActivity.java:141)
at android.app.Activity.performCreate(Activity.java:7963)
at android.app.Activity.performCreate(Activity.java:7952)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)
at com.qiyukf.unicorn.i.a.callActivityOnCreate(Unknown Source:2)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3479)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3643)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:140)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:100)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2229)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:238)
at android.app.ActivityThread.main(ActivityThread.java:7798)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:512)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:995)
Caused by: java.lang.RuntimeException: Using WebView from more than one process at once with the same data directory is not supported. https://crbug.com/558377
at org.chromium.android_webview.AwBrowserProcess.b(PG:11)
at D5.m(PG:33)
at D5.a(PG:48)
at D5.b(PG:16)
at com.android.webview.chromium.WebViewChromiumFactoryProvider.a(PG:32)
at com.android.webview.chromium.WebViewChromium.init(PG:12)
at android.webkit.WebView.<init>(WebView.java:435)
at android.webkit.WebView.<init>(WebView.java:359)
at android.webkit.WebView.<init>(WebView.java:342)
at android.webkit.WebView.<init>(WebView.java:329)
at com.xuetian.common.ui.lib.widget.LollipopFixedWebView.<init>(LollipopFixedWebView.java:24)
... 31 more
Back traces ends.
1疫蔓、Android Pie 行為變更——按進(jìn)程分設(shè)基于網(wǎng)絡(luò)的數(shù)據(jù)目錄
為改善 Android 9 中的應(yīng)用穩(wěn)定性和數(shù)據(jù)完整性身冬,應(yīng)用無法再讓多個進(jìn)程共用同一 WebView 數(shù)據(jù)目錄。 此類數(shù)據(jù)目錄一般存儲 Cookie滚躯、HTTP 緩存以及其他與網(wǎng)絡(luò)瀏覽有關(guān)的持久性和臨時性存儲嘿歌。
在大多數(shù)情況下,您的應(yīng)用只應(yīng)在一個進(jìn)程中使用 android.webkit 軟件包中的類丧凤,例如 WebView 和 CookieManager步脓。 例如,您應(yīng)該將所有使用 WebView 的 Activity 對象移入同一進(jìn)程仍侥。 您可以通過在應(yīng)用的其他進(jìn)程中調(diào)用 disableWebView()鸳君,更嚴(yán)格地執(zhí)行"僅限一個進(jìn)程”規(guī)則。該調(diào)用可防止 WebView 在這些其他進(jìn)程中被錯誤地初始化腿时,即使是從依賴內(nèi)容庫進(jìn)行的調(diào)用也能防止。
如果您的應(yīng)用必須在多個進(jìn)程中使用 WebView 的實例批糟,則必須先利用 WebView.setDataDirectorySuffix() 函數(shù)為每個進(jìn)程指定唯一的數(shù)據(jù)目錄后綴徽鼎,然后再在該進(jìn)程中使用 WebView 的給定實例。 該函數(shù)會將每個進(jìn)程的網(wǎng)絡(luò)數(shù)據(jù)放入其在應(yīng)用數(shù)據(jù)目錄內(nèi)自己的目錄中悄但。
注意:即使您使用setDataDirectorySuffix()
石抡,系統(tǒng)也不會跨應(yīng)用的進(jìn)程界限共享 Cookie 以及其他網(wǎng)絡(luò)數(shù)據(jù)。 如果應(yīng)用中的多個進(jìn)程需要訪問同一網(wǎng)絡(luò)數(shù)據(jù)嚎京,您需要自行在這些進(jìn)程之間復(fù)制數(shù)據(jù)隐解。 例如,您可以調(diào)用 getCookie() 和 setCookie()帕涌,在不同進(jìn)程之間手動傳輸 Cookie 數(shù)據(jù)蚓曼。
這個問題在去年初就遇到解決了一次炸宵,解決方式為在Application的oncreat方法里調(diào)用如下代碼:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
String processName =getProcessName();
if(processName.equals("com.xxx.xxx")){
WebView.setDataDirectorySuffix(processName);
}
}
當(dāng)時按這種方式解決之后錯誤日志統(tǒng)計也就沒再出現(xiàn)過該錯誤土全。直到去年底使用了加固服務(wù)之后突然又出現(xiàn)了該錯誤,錯誤率飆到了1.9%裹匙,不由得龍脊一緊。當(dāng)時懷疑是加固的問題籽御,但是手上沒有手機能復(fù)現(xiàn)該問題,使用錯誤統(tǒng)計的相同機型(機型版本:PCHM10铃将、PCLM50等)都復(fù)現(xiàn)不了哑梳。后來終于找到一個同事的手機復(fù)現(xiàn)了這個問題,而且是畢現(xiàn)(一加手機:OnePlus 9R)悯仙。
從再次遇到這個問題到徹底解決這個問題耗費了將近一天的時間吠卷,期間甚至懷疑剛購買的加固服務(wù)導(dǎo)致的。不過好在解決了货岭,使得錯誤率降低到了現(xiàn)在可接受的 0.09%序攘,下面大概說一下具體情況寻拂。
2、經(jīng)過多種嘗試最終發(fā)現(xiàn)以下方式可以解決
開始解決代碼:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
String processName =getProcessName();
if(processName.equals("com.xxx.xxx")){
WebView.setDataDirectorySuffix(processName);
}
}
修改后最終解決代碼:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
String processName =getProcessName();
WebView.setDataDirectorySuffix(processName);
}
該設(shè)備機型與系統(tǒng)WebView版本見下圖: