最近在后臺(tái)發(fā)現(xiàn)app報(bào)webview的錯(cuò)誤翁逞,主要原因是Android P的行為變更導(dǎo)致的。
WebView崩潰錯(cuò)誤
java.lang.RuntimeException
Using WebView from more than one process at once with the same data directory is not supported
解析
Android P行為變更箩祥,不可多進(jìn)程使用同一個(gè)目錄webView两芳,需要為不同進(jìn)程webView設(shè)置不同目錄。
Android P 變更
Android Pie ( API 級(jí)別 28 ) 是谷歌于 2018 年 8 月 7 日發(fā)布的正式版系統(tǒng)迈着。將 targetSdkVersion 設(shè)為 API 28 或更高級(jí)別的應(yīng)用必須進(jìn)行修改竭望,以便正確支持這些行為
模擬WebView錯(cuò)誤
第一步
將應(yīng)用的 targetSdkVersion 的 API 級(jí)別設(shè)為 28
第二步
通過(guò)兩個(gè)處于不同進(jìn)程的 Activity 分別使用 WebView 加網(wǎng)頁(yè)實(shí)現(xiàn)
第三步
為 Activity 設(shè)置進(jìn)程需要在 AndroidManifest.xml 文件中對(duì)應(yīng)的 Activity 節(jié)點(diǎn)下增加 process 屬性,并設(shè)置進(jìn)程名
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.zyb.webviewtest">
<application>
......
<activity
android:name=".TestWebViewActivity"
android:process=":ProcessName" />
......
</application>
</manifest>
注意:process 的命名不能以數(shù)字開(kāi)頭裕菠,否正會(huì)提示 Install failed咬清。
最后,在Android P 的模擬器或真機(jī)上運(yùn)行,就可以重現(xiàn)之前提到的錯(cuò)誤旧烧。如果沒(méi)有重現(xiàn)影钉,請(qǐng)將清單文件中 Application 節(jié)點(diǎn)下的 name 屬性注釋后重試。
修復(fù)WebView錯(cuò)誤
很顯然掘剪,webview的錯(cuò)誤是在不同進(jìn)程下導(dǎo)致的平委,也就是說(shuō)Android P針對(duì) WebView在不同進(jìn)程下無(wú)法訪問(wèn)非自己進(jìn)程中的webview目錄。
解決這個(gè)問(wèn)題夺谁,就需要兼容Android P廉赔,上代碼:
public class TestApplication extends Application {
private static final String PROCESSNAME = "com.zyb.webviewtest";
@Override
public void onCreate() {
super.onCreate();
//放在onCreate方法中,部分小米手機(jī)未生效匾鸥,同樣還會(huì)報(bào)錯(cuò)蜡塌,故放在分包時(shí)配置webview緩存
//initWebView();
}
@Override
protected void attachBaseContext (Context base) {
super.attachBaseContext(base);
initWebView();
MultiDex.install(this);
}
private void initWebView() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
String processName = getProcessName(this);
if (!PROCESSNAME.equals(processName)) {
WebView.setDataDirectorySuffix(getString(processName, "zyb"));
}
}
}
}
我們可以為每個(gè)進(jìn)程指定唯一的數(shù)據(jù)目錄后綴,再該進(jìn)程中使用WebView勿负。
在Application分包的時(shí)候設(shè)置對(duì)應(yīng)的WebView數(shù)據(jù)目錄后綴馏艾。
之前將webview的初始化放在Application中的onCreate()方法中,部分小米手機(jī)使用不生效奴愉,還是會(huì)報(bào)同樣的錯(cuò)誤琅摩。
所以將webview的初始化放在 方法中,也就是在分包時(shí)就初始化躁劣,最終解決了這個(gè)問(wèn)題~
為什么在Application初始化的時(shí)候設(shè)置呢迫吐?
Application的 attachBaseContext() 方法在分包時(shí)調(diào)用,我們可以在新開(kāi)進(jìn)程的時(shí)候拿到當(dāng)前的進(jìn)程名稱與主進(jìn)程進(jìn)行對(duì)比账忘,如果不一致志膀,我們就為該進(jìn)程指定對(duì)應(yīng)的WebView緩存目錄后綴。
最后
重新運(yùn)行在Android P上測(cè)試鳖擒,在App安裝路徑下 (data/data/包名) 會(huì)發(fā)現(xiàn)多一個(gè)對(duì)應(yīng)進(jìn)程后綴的webview緩存目錄溉浙。
最后,希望此篇博客對(duì)大家有所幫助蒋荚,歡迎提出問(wèn)題及建議共同探討戳稽,如有興趣可以關(guān)注我的博客,謝謝期升!