Android WebView已开始在Android 9上崩溃

时间:2019-05-17 23:29:40

标签: android webview crash android-9.0-pie

Hello Expert Android开发人员:

我们有一个android应用,我们的基本工作流程如下

  1. 通过电子邮件或短信向用户发送了一个链接
  2. 用户单击链接,然后在Chrome或Android默认浏览器上打开一个页面,页面上有一个名为 JOIN
  3. 的按钮
  4. 用户单击此 JOIN 按钮,我们的应用启动,并在Webview中显示一个页面,要求用户输入名字,姓氏和电话/电子邮件,然后用户单击名为初始化
  5. 我们验证信息-如果用户是新用户,我们将创建一条记录,该用户已存在,我们将其更新,等等,然后显示一个弹出窗口,通知他的会话将被记录。
  6. 只要用户在弹出窗口上单击“确定”,然后控件就存在Web视图,并且用户位于本机android页面上。

问题 在Webview上轻按“确定”按钮后,本机应用程序页面将正常启动,直到几周前,该应用程序崩溃,我们将被带回到Webview页面的开始,要求我们输入详细信息。

请注意以下注意事项:

  • 首先,这仅在Android 9的情况下发生。我们已经在三星Galaxy S8和S9上进行了测试。它并不是每次都发生,而是相当定期地发生,我有时甚至说三分之二。在最好的时候,它发生了十分之二,但确实发生了。
  • 此代码已在过去一年左右的时间内成功运行,我们从未遇到过此问题。它只是在最近3-4周内才开始发生。
  • 我们还有一个iOS应用,未发现相同的问题。

以下代码段可能会有所帮助-这就是我们加载网络视图的方式。

webview = findViewById(R.id.webview);
    webview.setVisibility(View.VISIBLE);
    final ProgressDialog pd = ProgressDialog.show(ActivtyName.this, "", "Please wait", true);
    webview.setGeolocationEnabled(true);
    webview.setMixedContentAllowed(true);
    webview.getSettings().setJavaScriptEnabled(true);
    webview.getSettings().setDomStorageEnabled(true);
    webview.getSettings().setLoadWithOverviewMode(true);

    webview.setWebChromeClient(new WebChromeClient()

========我们在此重写了许多方法,

webview.setWebViewClient(new WebViewClient()

========我们在这里覆盖方法。

有什么想法吗?在通过USB模式进行调试时,我们尝试查看日志,但是除了下面的Android控制台上显示的内容外,我们在日志中看不到太多内容:

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
pid: 0, tid: 0 >>> com.a****d.xyzapp <<<

backtrace:

#00  pc 0000000001b61620  /data/app/com.android.chrome-DpcaMBOCm2oa08upmw1Tug==/base.apk

以下是要求的更详细的日志:

2019-05-18 11:58:01.694 23217-23217/com.a**d.xyzapp.debug A/chromium: 

[FATAL:crashpad_client_linux.cc(404)] Render process (28925)'s crash wasn't handled by all associated  webviews, triggering application crash.
Fatal signal 5 (SIGTRAP), code 1 (TRAP_BRKPT), fault addr 0x7ab7b9d620 in tid 23217 (atientapp.debug), pid 23217 (atientapp.debug) (edited) 

6 个答案:

答案 0 :(得分:2)

尽管我的设备有6GB的内存,但是它仍然崩溃。 Android 8.0+上的webview是以这种方式实现的,如果webview不可见,其渲染过程将被拉出内存并销毁以节省内存。使用单行更改此实现。

webView.setRendererPriorityPolicy(WebView.RENDERER_PRIORITY_IMPORTANT, false);

将优先级设置为“重要”表示OS使您的渲染过程保持活动状态,“ false”表示不“在不可见时放弃内存”。

有关更多详细信息,请参见此处-https://developer.android.com/guide/webapps/managing-webview#renderer-importance

谢谢,编码愉快。

答案 1 :(得分:0)

这似乎是一个内存问题,可以从几个线程中找到。

在您的webview片段/活动中执行此操作,覆盖onLowMemory()并添加日志。

@Override
public void onLowMemory() {
    Log.d("TAG_MEMORY", "Memory is Low");
    super.onLowMemory();
}

现在尝试重现崩溃,并如果调用了onLowMemory(),那么这就是根本原因。也许某些Webview页面的内存过多。

答案 2 :(得分:0)

您是否正在使用mopub广告平台?如果是这样,则说明他们的SDK与该bug有关。
通常与正在尝试加载的网页错误有关。
从android 8.0开始,webview的工作方式也发生了变化。现在它是基于多进程的,它还使您能够处理这些类型的错误(渲染器消失,内存不足以及许多其他错误)。
您应该实现此覆盖

public boolean onRenderProcessGone(WebView view, RenderProcessGoneDetail detail)

关于此的更多详细信息是here

更新: 如果您使用的是mopub甚至是webview,则Android 9.0会阻止所有非https流量。考虑使用替代方式,例如mopub具有implemented here

答案 3 :(得分:0)

我希望这是我之前遇到的同样的问题。 Android 9在安全性方面发生了几处更改。因此,基本上,默认情况下,它会阻止所有不安全或未通过SSL认证的URL和域用于应用程序。

  

默认情况下启用网络TLS   如果您的应用程序针对Android 9或更高版本,则默认情况下,isCleartextTrafficPermitted()方法将返回false。如果您的应用需要为特定域启用明文,则必须在应用的网络安全配置中将这些域的cleartextTrafficPermitted设置为true。

您需要使该域经过SSL认证,然后将此代码添加到清单中

window\.DATA_STORE     match literal "window.DATA_STORE"
.*?                    followed by any content (across lines) until
(?=\(function\(\) \{)  looking ahead and seeing "(function() {"

还要在您的应用程序build.gradle文件依赖项块中添加以下代码:

<applicaton ....>
<uses-library
            android:name="org.apache.http.legacy"
            android:required="false" />
</application>

,如果您现在对保护域不满意,则还可以在网络配置中排除该域。本页中提到了详细的过程

Security configuration for android

答案 4 :(得分:0)

尝试使用

        android:usesCleartextTraffic="true"

在应用标签中- 在您的AndroidManifest中

答案 5 :(得分:0)

在您的情况下,渲染进程崩溃且未被系统终止。

here所述,如果您覆盖

onRenderProcessGone(WebView view,
            RenderProcessGoneDetail detail)

以上方法,则detail.didCrash()将在您的情况下保留true。在那种情况下,Renderer因内部错误(例如内存访问冲突)而崩溃。在检测到渲染器崩溃后,应用程序本身也崩溃了。

要处理崩溃并允许您的应用继续执行,请执行以下步骤:-

  1. 销毁当前的WebView实例。
  2. 指定您的业务逻辑,您的应用将如何继续执行。
  3. 覆盖onRenderProcessGone并返回true。
  

问题只要在网络视图上点击确定按钮,   本机应用程序页面将正常启动,直到几周前   崩溃,我们将被带回到Webview页面的开始   要求我们输入详细信息。

这是因为如果在加载特定网页时渲染器崩溃,则尝试再次加载该页面可能会导致新的WebView对象表现出相同的渲染崩溃行为。

查看this link中的代码以获取更多信息。

希望这会有所帮助。