19

Hello Expert Android Developers:

We have an android app and our basic workflow is as below

  1. User is sent a link via email or text message
  2. User clicks on the link and a page open on Chrome or Android default browser and have a button named JOIN
  3. User clicks on this JOIN button and our app is launched and a page is displayed in webview asking the User to enter the first name, last name and phone/email and then the user clicks on a button named INITIATE
  4. We validate the information - if the user is new, we create a record, it user is existing, we update it etc and then show a popup informing that his session would be recorded.
  5. As soon as the user clicks on OK on the popup and then the control exists the webview and the user is on a native android page.

Problem As soon as the OK button is tapped on the webview where our native app page would launch normally until a few weeks ago, the app crashes and we would be taken back to the start of the webview page asking us to enter the details.

Please note the below caveats:

  • First of all, this is happening only in the case of Android 9. We have tested this on Samsung Galaxy S8 and S9. And it doesn't happen every single time but it happens rather regularly, I would say sometimes even 2 out of 3 times. In the best of the times, it has happened 2 out of 10 times but it happens.
  • This code has been running successfully for the past 1 year or so and we never had this problem. It has only started happening in the last 3-4 weeks.
  • We also have an iOS app, where the same problem is not observed.

Here is a code snippet that may help - This is how we are loading the webview.

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()

=======We override a lot of methods here followed by

webview.setWebViewClient(new WebViewClient()

=======We override methods here.

Any idea what might be going on? We have tried looking at the logs while debugging via USB mode, but we don't see much in logs except what is shown on the Android Console like below:

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

backtrace:

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

Here is the more detailed log as requested:

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) 
Pravin Divraniya
  • 4,223
  • 2
  • 32
  • 49
cooler
  • 753
  • 4
  • 9
  • 18

6 Answers6

8

In your case Render process is crashing and it is not killed by the system.

So as described here, if you override

onRenderProcessGone(WebView view,
            RenderProcessGoneDetail detail)

above method then detail.didCrash() will holds true in your case. In that case, Renderer crashed because of an internal error, such as a memory access violation. The app itself crashes after detecting that the renderer crashed.

To handle the crash and allow your app to continue executing, you should follow the below steps:-

  1. Destroy the current WebView instance.
  2. Specify your business logic how your app can continue executing.
  3. Override onRenderProcessGone and return true.

Problem As soon as the OK button is tapped on the webview where our native app page would launch normally until a few weeks ago, the app crashes and we would be taken back to the start of the webview page asking us to enter the details.

This is because if a renderer crashes while loading a particular web page, attempting to load that same page again could cause a new WebView object to exhibit the same rendering crash behaviour.

Check code in this link for more info.

Hope this will help.

Pravin Divraniya
  • 4,223
  • 2
  • 32
  • 49
  • Another problem with this approach is that in case of multiple webviews, it's unfortunately not possible to determine which one crashed the app https://groups.google.com/a/chromium.org/g/android-webview-dev/c/MEAtYPfGx6Q – android_dev Feb 08 '22 at 15:23
3

Although my device have 6GB of memory, it still crashes. The webview on Android 8.0+ is implemented in this way that if webview is not visible it's render process will be pulled out of memory and destroyed to save memory. Change this implementation using a single line.

webView.setRendererPriorityPolicy(WebView.RENDERER_PRIORITY_IMPORTANT, false);

Setting priority to important indicates OS to keep your render process alive and "false" indicates to not "waive off memory when not visible".

See here for more details - https://developer.android.com/guide/webapps/managing-webview#renderer-importance

Thanks and happy coding.

Paras khandelwal
  • 1,345
  • 14
  • 13
  • 2
    Thanks for the info but it appears these are the default values so this would do nothing. You can verify this by calling `webView.getRendererRequestedPriority();` and `webView.getRendererPriorityWaivedWhenNotVisible();`. – Lorenzo Jun 18 '20 at 20:13
2

This seems like a memory issue, what I can find from few of the threads.

Do this, in your webview fragment/activity override onLowMemory() and add a log.

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

Now try to reproduce the crash, and if onLowMemory() is called then that is the root cause. Maybe some of the webview pages are too much memory.

TheAnkush
  • 885
  • 7
  • 10
2

Are you using mopub advertising platform? if so they have this bug associated with their sdk.
It is usually related to bug in web-page that is being tried to load.
There is also change in the way webview works from android 8.0 above. It is now multi-process based, which also gives you power to handle these kind of errors(renderer gone, out of memory and many others).
You should implement this override

public boolean onRenderProcessGone(WebView view, RenderProcessGoneDetail detail)

More detail about this is here

Update: If you are using mopub or even webview, Android 9.0 blocks all non-https traffic. Consider using alternate way like mopub has implemented here.

Vanshaj Daga
  • 2,145
  • 11
  • 18
0

I hope this is the same problem which i faced earlier. There are several changes takes place in Android 9 regards of security. So, basically by default it block all urls and domains to use in app which are not secured or SSL Certified.

Network TLS enabled by default If your app targets Android 9 or higher, the isCleartextTrafficPermitted() method returns false by default. If your app needs to enable cleartext for specific domains, you must explicitly set cleartextTrafficPermitted to true for those domains in your app's Network Security Configuration.

Either you need to make that domain SSL certified and add this code in manifest

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

also add the code below in your app build.gradle file dependencies block:

dependencies {
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
}

and if you are not comfortable with securing your domain right now, then you can also exclude that domain in network configuration. Detailed procedure is mentioned in this page

Security configuration for android

-1

Try Using

        android:usesCleartextTraffic="true"

in application tag - in Your AndroidManifest

  • You better elaborate more about this solution. But in my opinion, it's not an obvious fix for this problem. – pqtuan86 Dec 11 '19 at 09:10
  • Hi, im too using webview in my application after research it was found that java.io.IOException: Cleartext HTTP traffic to * was not permitted adding this to my manifest fixed my problem – Abubakar Rafi Sep 30 '20 at 05:03