安卓Webview在三星手机和安卓11上崩溃

9
这是我们在Firebase上看到的堆栈跟踪:
Fatal Exception: java.lang.RuntimeException
Using WebView from more than one process at once with the same data directory is not supported. https://crbug.com/558377 : Current process [Our package] (pid 28562), lock owner [Our package] (pid 13324)
org.chromium.android_webview.AwDataDirLock.b (AwDataDirLock.java:27)
as0.i (as0.java:30)
as0.b (as0.java:17)
as0.k (as0.java:2)
com.android.webview.chromium.WebViewChromiumFactoryProvider.g (WebViewChromiumFactoryProvider.java:2)
com.android.webview.chromium.WebViewChromium.init (WebViewChromium.java:14)
android.webkit.WebView.<init> (WebView.java:435)
android.webkit.WebView.<init> (WebView.java:355)
android.webkit.WebView.<init> (WebView.java:337)
android.webkit.WebView.<init> (WebView.java:324)
android.webkit.WebView.<init> (WebView.java:314)
[Our code initializing the webview]
android.os.Handler.handleCallback (Handler.java:938)
android.os.Handler.dispatchMessage (Handler.java:99)
android.os.Looper.loop (Looper.java:246)
android.app.ActivityThread.main (ActivityThread.java:8506)
java.lang.reflect.Method.invoke (Method.java)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:602)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1130)

我们无法重现此问题,但在Firebase上会出现数百/数千次这样的崩溃。奇怪的是,99%的崩溃发生在运行Android 11的Samsung设备上。我们的应用程序还是单进程应用程序,因此不应该运行多个进程。我已经在Chromium问题跟踪器中发布了帖子,但似乎错误与Samsung OS本身而不是Webview有关,因此我也想在这里发布帖子。
似乎有些用户的应用程序进程持续运行数小时,保留此Webview锁。但是,当他们尝试打开我们的应用程序时,它会启动一个新进程而不是现有进程,并导致崩溃。
我正在努力获取更多信息:有人了解为什么这种情况会特别发生在Samsung Android 11上吗?我们的应用程序或用户是否有什么方法来减轻此问题?有其他人遇到过这个问题并找到了解决方法吗?

你尝试过在Samsung设备上切换DeX模式吗?这是一个场景,在这种情况下,我可以看到三星在进程方面做了一些奇怪的事情。此外,您是否看到这些相同用户的其他崩溃情况?我想知道您的旧进程是否以未清理他们正在使用的锁定文件(?)的方式终止了。 - CommonsWare
@CommonsWare 我们在Firebase上跟踪用户ID,至少对于我现在和过去查看的少数用户来说,在过去90天内这是他们在Firebase上报告的唯一崩溃。我不知道是否可能像内存泄漏之类的原因导致了这个问题,但仍然很奇怪它会如此特定于三星。我从未听说过DeX模式,我们将研究一下并查看是否可以重现任何问题,谢谢! - jaregier
我可能错了,但是你是否正在使用这个本地化库(或类似的东西)?它的一个bug在我们的应用程序中创建了十几个崩溃,其中一个崩溃具有您提供的相同堆栈跟踪。 - Amin
我没有使用那个本地化库,而且无论如何,他们似乎已经修复了那个特定的问题。但是谢谢你的评论,Amin...我可能会尝试一些他们为了修复那个库所做的更改。 (尽管仍不清楚为什么这些崩溃集中在运行Android 11的三星设备上。) - Rapunzel Van Winkle
@RapunzelVanWinkle,你能找到问题的根源或解决方法吗? - Singed
显示剩余2条评论
2个回答

1

在初始化任何 WebView 相关的内容(如 AdMob)之前,尝试将此代码添加到应用程序类的 onCreate 中:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            String processName = getProcessName();
            if (!getPackageName().equals(processName)) {
                WebView.setDataDirectorySuffix(processName);
            }
        }

//AdMob 创建了一个新的进程。


0

我不记得确切的堆栈跟踪,但我遇到了与WebView在某些设备上返回应用程序时导致应用程序崩溃的类似问题。在没有解决方案的情况下,我尝试从XML中删除WebView定义,并将WebView初始化移动到Activity(Kotlin)中,并在onStop()方法中手动销毁。虽然没有找到问题的信息,但解决了我的问题。

   override fun onResume() {
        webView = WebView(activity)
        //... init webview
        webViewLayout.addView(webView)
   }
   override fun onStop() {
        webViewLayout.removeView(webView)
        webView?.destroy()
        webView = null
    }

编辑:感谢kingston指出我的错误。在代码中误读了webview的创建,这在onCreate()中没有意义,也不应该在onStop()中销毁。

如果您不需要在返回屏幕时刷新布局以节省资源,则可以将创建移动到onCreate()中,将销毁移动到onDestroy()中。在我们的情况下,需要在返回屏幕时始终更新内容。


你应该在 onStart 中创建 WebView,或者在 onDestroy 中销毁它。如果你按照现在的方式做,当你停止活动并在它被销毁之前重新启动它时,你会得到一个已销毁的 WebView。 - kingston
感谢您指出这个问题(编辑)。在我们的情况下,需要屏幕始终是实际的,这就是为什么它在onResume()中的原因。我从一个文件创建并从另一个文件销毁,没有注意到这一点。 - David Vareka
如果您在 onResume 中创建了 WebView,则需要在 onPause 中删除,否则在显示并关闭对话框时,将会出现多个 WebView 实例的情况:onPause 将被调用,然后再次调用 onResume 而没有调用 onStop。 - kingston
我所指的屏幕没有使用任何应用内对话框或其他部分覆盖来触发onPause()而不离开Activity,从而导致onStop()。为了确保,我尝试了一些屏幕操作(抽屉...),并且没有发现问题,但是如果您用对话框覆盖屏幕,则会调用onPause。在常规屏幕中,我们使用onCreate和onDestroy方法。 - David Vareka
你能提供任何支持你建议添加/删除WebView的文档吗?我不清楚为什么这是必要的。 - Rapunzel Van Winkle
没有文档,只有真实的使用案例。这个修复是在绝望中完成的,因为找不到解决方案。当Activity被销毁时,在某些设备上会发生崩溃,WebView会与Renderer进程崩溃(有时在应用程序退出后导致应用程序崩溃对话框)。我在某个论坛上发现(无法提供链接或堆栈跟踪,已经过一段时间),WebView实现在某些Android版本和某些设备上存在缺陷。在Redmi Android 9上成功测试。 - David Vareka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接