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
- Run the app on a 4 GB device with a non-trivial dataset.
- Use it normally, then background the app / let the screen sleep / open other apps to create memory pressure.
- Return to the app — Targets render empty.
- 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.
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
master(see analysis below)Steps to reproduce
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)WebViewClient(UrlHandler) overrides onlyonReceivedError(network/page-load errors). There is noonRenderProcessGoneoverride inUrlHandlerorEmbeddedBrowserActivity. So renderer-process death is not handled; per theWebViewClient.onRenderProcessGonecontract, 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.onTrimMemory/onLowMemoryhandling to proactively reduce footprint before a kill.Proposed fix
WebViewClient.onRenderProcessGone(WebView, RenderProcessGoneDetail): detect the renderer going away (distinguishingdidCrash()from a system kill), recreate/reload the WebView, andreturn trueso the app recovers automatically rather than being torn down. This is the standard pattern for long-lived WebView apps.onTrimMemoryhandling 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.