1、问题
使用webview加载网页,在应用运行时,报了如下错误:
android.webkit.WebViewFactory$MissingWebViewPackageException: Failed to load WebView provider: No WebView installed
2、分析
通过查看项目的修改记录,确实安装了WebView。打开cmd,执行adb shell "pm list packages | grep webview"该命令,可以看到安装的webview的包名。如图:
c
C:\Users\ABC1314>adb shell "pm list packages | grep webview"
package:com.google.android.webview
3、解决
系统是通过SystemImpl.java获取config_webview_packages.xml文件中定义的WebView
路径:frameworks/base/services/core/java/com/android/server/webkit/SystemImpl.java
java
private SystemImpl() {
int numFallbackPackages = 0;
int numAvailableByDefaultPackages = 0;
XmlResourceParser parser = null;
List<WebViewProviderInfo> webViewProviders = new ArrayList<WebViewProviderInfo>();
try {
parser = AppGlobals.getInitialApplication().getResources().getXml(
com.android.internal.R.xml.config_webview_packages);
XmlUtils.beginDocument(parser, TAG_START);
while(true) {
XmlUtils.nextElement(parser);
String element = parser.getName();
if (element == null) {
break;
}
if (element.equals(TAG_WEBVIEW_PROVIDER)) {
String packageName = parser.getAttributeValue(null, TAG_PACKAGE_NAME);
if (packageName == null) {
throw new AndroidRuntimeException(
"WebView provider in framework resources missing package name");
}
String description = parser.getAttributeValue(null, TAG_DESCRIPTION);
if (description == null) {
throw new AndroidRuntimeException(
"WebView provider in framework resources missing description");
}
boolean availableByDefault = "true".equals(
parser.getAttributeValue(null, TAG_AVAILABILITY));
boolean isFallback = "true".equals(
parser.getAttributeValue(null, TAG_FALLBACK));
WebViewProviderInfo currentProvider = new WebViewProviderInfo(
packageName, description, availableByDefault, isFallback,
readSignatures(parser));
if (currentProvider.isFallback) {
numFallbackPackages++;
if (!currentProvider.availableByDefault) {
throw new AndroidRuntimeException(
"Each WebView fallback package must be available by default.");
}
if (numFallbackPackages > 1) {
throw new AndroidRuntimeException(
"There can be at most one WebView fallback package.");
}
}
if (currentProvider.availableByDefault) {
numAvailableByDefaultPackages++;
}
webViewProviders.add(currentProvider);
}
else {
Log.e(TAG, "Found an element that is not a WebView provider");
}
}
} catch (XmlPullParserException | IOException e) {
throw new AndroidRuntimeException("Error when parsing WebView config " + e);
} finally {
if (parser != null) parser.close();
}
if (numAvailableByDefaultPackages == 0) {
throw new AndroidRuntimeException("There must be at least one WebView package "
+ "that is available by default");
}
mWebViewProviderPackages =
webViewProviders.toArray(new WebViewProviderInfo[webViewProviders.size()]);
}
查看frameworks/base/core/res/res/xml/config_webview_packages.xml文件中对使用的webview进行声明:如下
java
<!-- The default WebView implementation -->
<webviewprovider description="Android WebView" packageName="com.android.webview" availableByDefault="true">
</webviewprovider>
可以看到,在该文件中声明的webview的包名是:com.android.webview,而我们通过adb命令看到系统安装的webview包名是com.google.android.webview,二者不同,导致了无法找到webview.
只需要在该xml文件中,将我们安装的webview添加进去即可。
java
<webviewproviders>
<webviewprovider description="Google WebView" packageName="com.google.android.webview" availableByDefault="true">
</webviewprovider>
<webviewprovider description="Trichromelibrary" packageName="com.google.android.trichromelibrary" availableByDefault="true">
</webviewprovider>
<!-- The default WebView implementation -->
<webviewprovider description="Android WebView" packageName="com.android.webview" availableByDefault="true">
</webviewprovider>
</webviewproviders>