[PR #233] Keep the page across process death #234

Open
opened 2026-10-29 12:17:17 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/cylonid/NativeAlphaForAndroid/pull/233
Author: @dkodr
Created: 9/11/2026
Status: 🔄 Open

Base: dev ← Head: feat/webview-state


📝 Commits (2)

  • a51f21c Keep the page across process death
  • 5c08ce2 Enable the back-forward cache

📊 Changes

2 files changed (+22 additions, -5 deletions)

View changed files

📝 app/build.gradle (+1 -1)
📝 app/src/main/java/com/cylonid/nativealpha/WebViewActivity.java (+21 -4)

📄 Description

WebViewActivity saves no state, so when Android reclaims the process the activity
comes back on the start URL with the scroll position, open view and form contents
gone. Cookies live on disk, so it was never a logout — but every reclaim throws the
user back to the top of the app.

Saving

Through WebViewCompat.saveState rather than the framework WebView.saveState.
The 1MB savedInstanceState budget is shared by the whole process, and web apps
without sandboxing all live in the main one, so several open web apps can exceed it
together and crash with TransactionTooLargeException. The Jetpack call takes a byte
budget and drops the oldest history entries to fit, without touching the live history,
so backward navigation stays intact. Forward entries are dropped as well, since there
is no forward button in the UI.

Only saves where the WebView reports SAVE_STATE. Falling back to the framework call
would reintroduce exactly the crash the budget exists to prevent, so older WebViews
keep today's behaviour instead — no restore, but no new failure mode either.

The second commit turns on the back-forward cache, so going back inside a web app
restores the previous page from memory instead of re-running the load.

androidx.webkit goes 1.13.0 → 1.17.0 for both. It needs minCompileSdk 33, which is
lower than the 34 required by 1.13.0, so this is independent of the targetSdk work
in #231 and applies to dev as it stands.

Testing

On a Pixel running Android 17 (API 37, WebView 151), killing the backgrounded process
with am kill to reproduce what the system does under memory pressure:

  • One web app scrolled deep into a page: comes back at the same position instead of
    at the top.
  • Three web apps open at once, all in the same process, all with history: every one
    restored, no TransactionTooLargeException, no crash in logcat. This is the case
    the byte budget exists for.
  • A web app with access restriction enabled: the prompt still appears and the content
    stays hidden until it is answered, so the biometric path is unaffected.

Not verified: that the back-forward cache actually shortens back navigation. Enabling
the flag follows the documented API, but I could not measure the difference without
instrumenting WebView's network activity, so treat that commit as untested rather than
proven.

One thing I noticed while testing and did not touch: setupWebView() runs
unconditionally after the biometric branch in onCreate, so a protected web app
issues its network request before the prompt is answered. The content is not shown —
the view is hidden — so this is not a visual leak, and it predates this change. Happy
to fix it separately if you want.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/cylonid/NativeAlphaForAndroid/pull/233 **Author:** [@dkodr](https://github.com/dkodr) **Created:** 9/11/2026 **Status:** 🔄 Open **Base:** `dev` ← **Head:** `feat/webview-state` --- ### 📝 Commits (2) - [`a51f21c`](https://github.com/cylonid/NativeAlphaForAndroid/commit/a51f21cfce9d43f05d4ff8f7cb23b29b9a3708f0) Keep the page across process death - [`5c08ce2`](https://github.com/cylonid/NativeAlphaForAndroid/commit/5c08ce277c9e830f77df5a4674c3485e02f10d84) Enable the back-forward cache ### 📊 Changes **2 files changed** (+22 additions, -5 deletions) <details> <summary>View changed files</summary> 📝 `app/build.gradle` (+1 -1) 📝 `app/src/main/java/com/cylonid/nativealpha/WebViewActivity.java` (+21 -4) </details> ### 📄 Description `WebViewActivity` saves no state, so when Android reclaims the process the activity comes back on the start URL with the scroll position, open view and form contents gone. Cookies live on disk, so it was never a logout — but every reclaim throws the user back to the top of the app. ## Saving Through [`WebViewCompat.saveState`][1] rather than the framework `WebView.saveState`. The 1MB `savedInstanceState` budget is [shared by the whole process][2], and web apps without sandboxing all live in the main one, so several open web apps can exceed it together and crash with `TransactionTooLargeException`. The Jetpack call takes a byte budget and drops the oldest history entries to fit, without touching the live history, so backward navigation stays intact. Forward entries are dropped as well, since there is no forward button in the UI. Only saves where the WebView reports `SAVE_STATE`. Falling back to the framework call would reintroduce exactly the crash the budget exists to prevent, so older WebViews keep today's behaviour instead — no restore, but no new failure mode either. The second commit turns on the back-forward cache, so going back inside a web app restores the previous page from memory instead of re-running the load. `androidx.webkit` goes 1.13.0 → 1.17.0 for both. It needs `minCompileSdk` 33, which is lower than the 34 required by 1.13.0, so this is independent of the targetSdk work in #231 and applies to `dev` as it stands. [1]: https://developer.android.com/reference/androidx/webkit/WebViewCompat#saveState(android.webkit.WebView,android.os.Bundle,int) [2]: https://developer.android.com/develop/ui/views/layout/webapps/manage-state ## Testing On a Pixel running Android 17 (API 37, WebView 151), killing the backgrounded process with `am kill` to reproduce what the system does under memory pressure: - One web app scrolled deep into a page: comes back at the same position instead of at the top. - Three web apps open at once, all in the same process, all with history: every one restored, no `TransactionTooLargeException`, no crash in logcat. This is the case the byte budget exists for. - A web app with access restriction enabled: the prompt still appears and the content stays hidden until it is answered, so the biometric path is unaffected. Not verified: that the back-forward cache actually shortens back navigation. Enabling the flag follows the documented API, but I could not measure the difference without instrumenting WebView's network activity, so treat that commit as untested rather than proven. One thing I noticed while testing and did not touch: `setupWebView()` runs unconditionally after the biometric branch in `onCreate`, so a protected web app issues its network request before the prompt is answered. The content is not shown — the view is hidden — so this is not a visual leak, and it predates this change. Happy to fix it separately if you want. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cylonid/NativeAlphaForAndroid#234
No description provided.