异常 webview

我收到 Crashlytics 的错误信息,表明有些设备缺少 com.google.android.webview。这怎么可能呢?

java.lang.RuntimeException: Unable to start activity   ComponentInfo{com.myapp.app/com.myapp.ReaderActivity}: android.view.InflateException: Binary XML file line #29: Error inflating class com.myapp.MyWebView
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: android.view.InflateException: Binary XML file line #29: Error inflating class com.myapp.MyWebView
at android.view.LayoutInflater.createView(LayoutInflater.java:633)
at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.createCustomViewInternal(SourceFile:206)
at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.access$000(SourceFile:20)
at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater$PrivateWrapperFactory2.onCreateView(SourceFile:297)
at android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:177)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:733)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:809)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:809)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.inflate(SourceFile:60)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
at android.support.v7.app.ActionBarActivityDelegateBase.setContentView(SourceFile:228)
at android.support.v7.app.ActionBarActivity.setContentView(SourceFile:102)
at com.myapp.ReaderActivity.onCreate(SourceFile:120)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance(Constructor.java)
at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
at android.view.LayoutInflater.createView(LayoutInflater.java:607)
at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.createCustomViewInternal(SourceFile:206)
at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.access$000(SourceFile:20)
at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater$PrivateWrapperFactory2.onCreateView(SourceFile:297)
at android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:177)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:733)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:809)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:809)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.inflate(SourceFile:60)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
at android.support.v7.app.ActionBarActivityDelegateBase.setContentView(SourceFile:228)
at android.support.v7.app.ActionBarActivity.setContentView(SourceFile:102)
at com.myapp.ReaderActivity.onCreate(SourceFile:120)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: android.util.AndroidRuntimeException: android.content.pm.PackageManager$NameNotFoundException: com.google.android.webview
at android.webkit.WebViewFactory.getFactoryClass(WebViewFactory.java:161)
at android.webkit.WebViewFactory.getProvider(WebViewFactory.java:101)
at android.webkit.WebView.getFactory(WebView.java:2185)
at android.webkit.WebView.ensureProviderCreated(WebView.java:2180)
at android.webkit.WebView.setOverScrollMode(WebView.java:2239)
at android.view.View.(View.java:3581)
at android.view.View.(View.java:3675)
at android.view.ViewGroup.(ViewGroup.java:491)
at android.widget.AbsoluteLayout.(AbsoluteLayout.java:55)
at android.webkit.WebView.(WebView.java:538)
at android.webkit.WebView.(WebView.java:483)
at android.webkit.WebView.(WebView.java:466)
at android.webkit.WebView.(WebView.java:453)
at com.myapp.MyWebView.(SourceFile:31)
at java.lang.reflect.Constructor.newInstance(Constructor.java)
at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
at android.view.LayoutInflater.createView(LayoutInflater.java:607)
at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.createCustomViewInternal(SourceFile:206)
at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.access$000(SourceFile:20)
at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater$PrivateWrapperFactory2.onCreateView(SourceFile:297)
at android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:177)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:733)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:809)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:809)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.inflate(SourceFile:60)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
at android.support.v7.app.ActionBarActivityDelegateBase.setContentView(SourceFile:228)
at android.support.v7.app.ActionBarActivity.setContentView(SourceFile:102)
at com.myapp.ReaderActivity.onCreate(SourceFile:120)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: android.content.pm.PackageManager$NameNotFoundException: com.google.android.webview
at android.app.ApplicationPackageManager.getPackageInfo(ApplicationPackageManager.java:114)
at android.webkit.WebViewFactory.getFactoryClass(WebViewFactory.java:133)
at android.webkit.WebViewFactory.getProvider(WebViewFactory.java:101)
at android.webkit.WebView.getFactory(WebView.java:2185)
at android.webkit.WebView.ensureProviderCreated(WebView.java:2180)
at android.webkit.WebView.setOverScrollMode(WebView.java:2239)
at android.view.View.(View.java:3581)
at android.view.View.(View.java:3675)
at android.view.ViewGroup.(ViewGroup.java:491)
at android.widget.AbsoluteLayout.(AbsoluteLayout.java:55)
at android.webkit.WebView.(WebView.java:538)
at android.webkit.WebView.(WebView.java:483)
at android.webkit.WebView.(WebView.java:466)
at android.webkit.WebView.(WebView.java:453)
at com.myapp.MyWebView.(SourceFile:31)
at java.lang.reflect.Constructor.newInstance(Constructor.java)
at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
at android.view.LayoutInflater.createView(LayoutInflater.java:607)
at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.createCustomViewInternal(SourceFile:206)
at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.access$000(SourceFile:20)
at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater$PrivateWrapperFactory2.onCreateView(SourceFile:297)
at android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:177)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:733)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:809)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:809)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.inflate(SourceFile:60)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
at android.support.v7.app.ActionBarActivityDelegateBase.setContentView(SourceFile:228)
at android.support.v7.app.ActionBarActivity.setContentView(SourceFile:102)
at com.myapp.ReaderActivity.onCreate(SourceFile:120)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

And it is only from devices running Lollipop. I have tested it on my Nexus 5, but I can not reproduce the error. I am using proguard

我的 MyWebView 是这样的:

public class MyWebView extends WebView {


public static final String tag = MyWebView.class.getName();
private HtmlJSInterfaceNew js;


public MyWebView(Context context) {
super(context);
gd = new GestureDetector(context, sogl);
init();
}


public MyWebView(Context context, AttributeSet attrs) {
super(context, attrs);
gd = new GestureDetector(context, sogl);
init();
}


public MyWebView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
gd = new GestureDetector(context, sogl);
init();
}


@SuppressLint("NewApi")
private void init() {
setPadding(0, 0, 0, 0);
MyWebViewClient myWebViewClient = new MyWebViewClient();
this.setWebViewClient(myWebViewClient);
setWebChromeClient(new MyWebChromeClient());
if(!isInEditMode())
{
getSettings().setAllowFileAccess(true);
getSettings().setJavaScriptCanOpenWindowsAutomatically(false);
getSettings().setJavaScriptEnabled(true);
WebSettings webSettings = getSettings();


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
webSettings.setAllowContentAccess(false);
}


webSettings.setUseWideViewPort(true);




}




}
public void addMyJavascriptInterface(HtmlJSInterfaceNew htmlJSInterface, String string) {
js = htmlJSInterface;
addJavascriptInterface(htmlJSInterface, string);
}


public class MyWebChromeClient extends WebChromeClient
{
public void onProgressChanged(WebView view, int progress) {
}
}
}

最根本的原因是:

android.util.AndroidRuntimeException: android.content.pm.PackageManager$NameNotFoundException: com.google.android.webview
at android.webkit.WebViewFactory.getFactoryClass(WebViewFactory.java:161)

所以我认为它可能与前卫和 JavascriptInterface 有关,有什么想法吗?

编辑: 我从 grepcode 中找到了 getFactoryClass 方法:

private static Class<WebViewFactoryProvider> getFactoryClass() throws ClassNotFoundException {
Application initialApplication = AppGlobals.getInitialApplication();
try {
// First fetch the package info so we can log the webview package version.
String packageName = getWebViewPackageName();
sPackageInfo = initialApplication.getPackageManager().getPackageInfo(packageName, 0);
Log.i(LOGTAG, "Loading " + packageName + " version " + sPackageInfo.versionName +
" (code " + sPackageInfo.versionCode + ")");


// Construct a package context to load the Java code into the current app.
Context webViewContext = initialApplication.createPackageContext(packageName,
Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
initialApplication.getAssets().addAssetPath(
webViewContext.getApplicationInfo().sourceDir);
ClassLoader clazzLoader = webViewContext.getClassLoader();
Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "Class.forName()");
try {
return (Class<WebViewFactoryProvider>) Class.forName(CHROMIUM_WEBVIEW_FACTORY, true,
clazzLoader);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW);
}
} catch (PackageManager.NameNotFoundException e) {
// If the package doesn't exist, then try loading the null WebView instead.
// If that succeeds, then this is a device without WebView support; if it fails then
// swallow the failure, complain that the real WebView is missing and rethrow the
// original exception.
try {
return (Class<WebViewFactoryProvider>) Class.forName(NULL_WEBVIEW_FACTORY);
} catch (ClassNotFoundException e2) {
// Ignore.
}
Log.e(LOGTAG, "Chromium WebView package does not exist", e);
throw new AndroidRuntimeException(e);
}
}
40382 次浏览

这很可能发生在棒棒糖的 Android 系统 WebView 应用程序更新后很短的时间内。

我曾经在 Google Play 开发控制台上看到过这个错误,但是从来没有在我的 Nexus 5上重现过,无论我多么努力地阻止我的应用访问 Android System WebView 应用:

java.lang.RuntimeException: Unable to create application com.uninteresting.app.name:
android.util.AndroidRuntimeException: android.content.pm.PackageManager$NameNotFoundException: com.google.android.webview

然后我们得到消息,我们的应用程序一直崩溃与上述信息在一些设备上的系统 WebView 应用程序更新后立即,所以我测试。仍然没有结果,香草 Nexus5拒绝崩溃我们的应用程序!所以我试用了其他制造商的手机(大约75% 的报告来自三星 Galaxy 设备) ,突然之间,我们的手机一直在崩溃。我的测试方法:

  1. 打开应用程序,确保显示 WebView。
  2. 打开 Play Store,导航到“ My Apps”,然后打开“ Android System” 卸载更新。这不应该让你崩溃,但你 应该会看到你的应用强制重启。
  3. 重新打开你的应用程序,让它从重启中恢复。
  4. 回到播放商店并更新 Android 系统 WebView。
  5. Re-focus your app during the update process. Now, if you're on an 受影响的设备,它应该崩溃。如果没有,你的应用程序将只是 被推到后面,静静地重新开始。

对于我目前所说的话,有几点需要注意的地方:

  • 我们的应用程序犯了一个错误,启动了一个 WebView非常早,因此我们得到“无法创建应用程序”在我们的崩溃消息。用户甚至不需要看我们的应用程序就会崩溃。我怀疑这对你是否适用,但是如果你的应用试图在这个场景中重新启动它包含 WebView 的活动,这就可以解释了。
  • 我们的报告100% 来自5.0设备,我完全不知道这怎么会发生在棒棒糖之下。
  • 我们确实看到了关于 Nexus4和 Nexus5的报道,所以我不知道为什么我不能在这些设备上重现这个错误。可能是另一个根本原因,但我需要进一步调查。

简而言之,我不会立即认为您在使用 ProGuard 或 JavascriptInterface 时做了任何不正确的事情。我强烈倾向于把大多数报告的根本原因归咎于固件,结果本应该是一个平稳的更新过程变成了一个导致一些应用程序彻底崩溃的过程。

Edit: I ran a few more tests and it turns out that all the devices that didn't crash are 5.0 or 5.0.1, while all the devices that did crash were 5.0.2, so I can't comfortably point my finger at OEMs anymore.

当安卓系统上的 chrome 更新时会发生这种情况: 在更新过程中,软件包没有被计算为已安装,因此尝试在软件包管理器中查找它将会失败。

对于我的情况,它持续了一段时间(应用程序不断崩溃) ,直到我实际上 重新启动/重新启动设备,然后一切都很好。

您的代码没有任何问题,只是处理更新的方式有问题。

资料来源: https://bugs.chromium.org/p/chromium/issues/detail?id=506369

我找到了重现问题的方法(Htc one (m8) android 6.0)。
在我的应用程序中,我在开始时使用 Android 系统 WebView组件(在 OnCreate ()方法中)。我知道这是不好的做法,但这只是例子。

步骤:

  1. 打开 Google Play并删除 < strong > Android 系统的更新 WebView
  2. launch your app
  3. 回到 Google Play发射 快速安装 Android 系统 WebView的更新 返回到你的应用程序,等待你的应用程序关闭
  4. 重复 第一步,快速返回到你的应用程序
  5. 您将看到错误报告
  6. 抱歉我的英语不好。

使用 Androidx.webkit库检查的简单方法:

dependencies {
...
implementation 'androidx.webkit:webkit:1.4.0'
}

使用 GetCurrentWebViewPackage方法之前(例如,广告) :

val webViewPackageInfo = WebViewCompat.getCurrentWebViewPackage(appContext)
Timber.d("📦 web view package info: %s", webViewPackageInfo?.toString())
val isWebViewPackageAvailable = webViewPackageInfo != null
prepareWithAds(canPlayAds = isWebViewPackageAvailable)

复制步骤:

  1. 禁用或删除系统 WebView 服务
  • 残疾: 进入系统设置菜单-> 应用程序-> Android 系统 WebView-> 禁用
  • Delete:
adb root
adb shell pm uninstall -k --user 0 com.google.android.webview
  1. 打开 smth WebView
  2. 如果软件包不可用,WebView 将崩溃:

E/WebViewFactory: Chromium WebView 包不存在 Webkit. WebViewFactory $MissingWebViewPackageException: 失败 加载 WebView 提供程序: 没有安装 WebView