Skip to content

App shows blank/empty data (e.g. Targets) until manual restart when the WebView renderer is killed on low-RAM devices (no onRenderProcessGone handling) #435

Description

@iesmail-znz

Describe the bug

On low-RAM Android devices, the CHT app intermittently appears to "lose" its data — sections such as Targets suddenly render empty. No data is actually lost (no re-sync is required afterwards); a full device restart brings everything back. This strongly suggests the WebView renderer process is being killed under memory pressure and the app does not recover until it is rebuilt from scratch.

Targets is usually where it shows first because that view is computed on load by the rules engine, so it's the first thing to go blank when the WebView runtime is unhealthy even though the underlying docs are intact.

Environment

  • Device: Samsung Galaxy Tab A9+, 4 GB RAM (confirmed), One UI (aggressive background-process / memory management)
  • cht-android: gap present through the latest release v1.7.0 / master (see analysis below)
  • cht-core: 5.1.0
  • Deployment: offline CHWs with sizeable catchments (large local PouchDB/IndexedDB footprint)

Steps to reproduce

  1. Run the app on a 4 GB device with a non-trivial dataset.
  2. Use it normally, then background the app / let the screen sleep / open other apps to create memory pressure.
  3. Return to the app — Targets render empty.
  4. Relaunching the app may not recover it; a device restart reliably does.

Expected behavior

When the WebView renderer process is killed, the app should detect it and gracefully recover (recreate/reload the WebView) so the user transparently gets their data back — instead of being left with a blank UI until a manual device restart.

Analysis (code references, master)

  • The WebViewClient (UrlHandler) overrides only onReceivedError (network/page-load errors). There is no onRenderProcessGone override in UrlHandler or EmbeddedBrowserActivity. So renderer-process death is not handled; per the WebViewClient.onRenderProcessGone contract, if the app doesn't handle it the default outcome is the WebView being left non-functional / the hosting process terminated — with no in-app reload.
  • android:largeHeap="true" is already set in the manifest, but that only enlarges the app's Java heap; it does not prevent the OS from reclaiming the separate renderer process under system-wide memory pressure.
  • There is no onTrimMemory / onLowMemory handling to proactively reduce footprint before a kill.

Proposed fix

  • Override WebViewClient.onRenderProcessGone(WebView, RenderProcessGoneDetail): detect the renderer going away (distinguishing didCrash() from a system kill), recreate/reload the WebView, and return true so the app recovers automatically rather than being torn down. This is the standard pattern for long-lived WebView apps.
  • Optionally show a brief "restoring…" state during recovery, and add onTrimMemory handling to lower the chance of a kill.

Impact

On 4 GB devices — e.g. the Samsung Galaxy Tab A9+, a common low-cost deployment tablet — this manifests as apparent data loss to CHWs, which erodes trust and disrupts fieldwork, and is only worked around by restarting the device. A renderer-gone handler would convert this into transparent in-app recovery.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions