最近在將工程海外版targetVersion升到10之后發(fā)現(xiàn)線上出現(xiàn)一個(gè)數(shù)量級很高的崩潰:
"Using WebView from more than one process at once with the same data directory is not supported. https://crbug.com/558377 : Current process...“
參考了谷歌的Webview.setDataDirectorysuffix()方案,卻引入了“webview already inited”WebView已經(jīng)初始化的新問題闻察,最后經(jīng)過不斷的分析拱礁,終于敲定
把Webview.setDataDirectorysuffix()放在application的attach生命周期
解決了這個(gè)問題,下面的復(fù)盤供大家參考辕漂。
場景復(fù)盤:
-
在一開始為了定位發(fā)生的場景花了不少時(shí)間呢灶,最后推斷是應(yīng)用首次初始化的時(shí)候發(fā)生的,如何分析的:
- 沒有用戶在反饋系統(tǒng)里反饋這個(gè)問題
- 崩潰次數(shù)和發(fā)生用戶比例幾乎就是1:1
- “webview already inited”改崩潰信息也反映出發(fā)生時(shí)刻是在初始化
-
從源碼的角度分析谷歌Webview.setDataDirectorysuffix()方案到底有沒有用
首先這里還有個(gè)疑惑钉嘹,為什么這個(gè)崩潰只在targetVersion升級后發(fā)生在高版本鸯乃,通過閱讀源碼發(fā)現(xiàn):
AwDataDirLock.java
我們知道andriod9(P)版本開始WebView使用的是獨(dú)立進(jìn)程,所以此處可以認(rèn)為谷歌為了規(guī)范這個(gè)使用在系統(tǒng)版本和目標(biāo)版本在9和9以上如果WebView使用不當(dāng)就會拋出多進(jìn)程異常跋涣,具體原因如下:
carashReason
可見此處如果sLockFile加鎖失敗缨睡,就會拋出之前的異常,此處的sLockFile指向Webview的緩存目錄陈辱,路徑是:/data/data/包名/cache/app_webview目錄下奖年。
這也解釋了為什么此處谷歌直接拋出多進(jìn)程異常,因?yàn)檫@是WebView的私有緩存目錄沛贪,通常只有WebView自身的操作才會讀寫陋守,只有在多進(jìn)程WebView啟動(dòng)的情況下,前一個(gè)進(jìn)程還在鎖定緩存文件目錄操作利赋,后一個(gè)進(jìn)程也要加鎖水评,才會失敗。 -
解決方案思考
最合適的方案應(yīng)該是規(guī)范WebView的使用媚送,不要給WebView單獨(dú)開進(jìn)程中燥,都使用系統(tǒng)獨(dú)立進(jìn)程使用WebView但是在項(xiàng)目中分析是第三方sdk引起的,不好推進(jìn)修改
-
Webview.setDataDirectorysuffix()方案為何失敗塘偎,Webview.setDataDirectorysuffix()是為每個(gè)進(jìn)程設(shè)置不同的目錄疗涉,確實(shí)解決了上述問題,但是分析源碼的過程中吟秩,我們知道這個(gè)過程是發(fā)生在WebView對緩存目錄加載的過程博敬,這和線上場景分析發(fā)生在應(yīng)用首次初始化是吻合的,所以我們要在緩存目錄加載加載之前設(shè)置峰尝,于是最終的方案:
把Webview.setDataDirectorysuffix()放在application的attach生命周期
這樣就可以保證在任何業(yè)務(wù)驅(qū)使的Webview初始化都在Webview.setDataDirectorysuffix()之后了偏窝。