NativeScript WebView安卓返回键异常:直接退出应用且状态未保存求助
Got it, let's work through these two WebView issues you're facing in NativeScript—they're super common and we can fix them with a few targeted tweaks.
Right now, the Android back button is triggering the app's default exit behavior instead of navigating back in the WebView. We can override this by listening to the backPressed event and checking if the WebView has a previous page to navigate to.
Step 1: Set up your WebView with an ID
First, make sure your WebView has an id in your XML layout so we can reference it in code:
<Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="onPageLoaded" unloaded="onPageUnloaded"> <WebView id="webView" src="https://your-target-url.com" /> </Page>
Step 2: Add Back Button Logic
In your page's code-behind (TypeScript/JavaScript), listen for the Android back press event, check if the WebView can go back, and trigger the navigation if possible:
import { Application, WebView, Page } from '@nativescript/core'; let webView: WebView; export function onPageLoaded(args) { const page = args.object as Page; webView = page.getViewById('webView') as WebView; // Attach back press listener for Android if (Application.android) { Application.android.on('backPressed', handleBackPressed); } } function handleBackPressed(event) { // Check if WebView can navigate back if (webView?.android?.canGoBack()) { webView.android.goBack(); event.cancel = true; // Prevent default app exit } // If no back history exists, let the default exit behavior run } // Clean up listener when page is unloaded to avoid memory leaks export function onPageUnloaded() { if (Application.android) { Application.android.off('backPressed', handleBackPressed); } }
When your app is minimized and reopened, the WebView is reloading because NativeScript doesn't persist its state by default. We'll handle this by saving the WebView's state when the app suspends and restoring it when it resumes.
Step 1: Add Suspend/Resume Listeners
Update your page code to save the WebView state when the app is suspended, and restore it when it resumes. We'll handle Android and iOS separately since their WebView APIs differ:
import { Application, WebView, Page } from '@nativescript/core'; let webView: WebView; let webViewState: any; // Holds saved state across suspend/resume export function onPageLoaded(args) { const page = args.object as Page; webView = page.getViewById('webView') as WebView; // ... keep existing back button code here ... // Attach suspend/resume listeners Application.on('suspend', handleAppSuspend); Application.on('resume', handleAppResume); // Enable cache and DOM storage for better state retention configureWebViewSettings(); } function configureWebViewSettings() { if (webView.android) { const settings = webView.android.getSettings(); settings.setCacheMode(android.webkit.WebSettings.LOAD_CACHE_ELSE_NETWORK); settings.setDomStorageEnabled(true); // Enable DOM storage for web apps settings.setAppCacheEnabled(true); } else if (Application.ios) { webView.ios.configuration.websiteDataStore = WKWebsiteDataStore.defaultDataStore(); webView.ios.configuration.preferences.setValueForKey(true, 'allowFileAccessFromFileURLs'); } } function handleAppSuspend() { if (!webView) return; if (Application.android) { // Save Android WebView state using Bundle const bundle = new android.os.Bundle(); webView.android.saveState(bundle); webViewState = bundle; } else if (Application.ios) { // Save iOS WebView state (current URL + scroll position) webViewState = { url: webView.ios.URL?.absoluteString, scrollOffset: webView.ios.scrollView.contentOffset }; } } function handleAppResume() { if (!webView || !webViewState) return; if (Application.android) { // Restore Android WebView state webView.android.restoreState(webViewState); } else if (Application.ios) { // Restore iOS WebView: reload URL and scroll to saved position if (webViewState.url) { webView.src = webViewState.url; // Wait for page to load before restoring scroll position webView.once('loadFinished', () => { webView.ios.scrollView.setContentOffsetAnimated(webViewState.scrollOffset, false); }); } } } export function onPageUnloaded() { // ... keep existing back button cleanup here ... Application.off('suspend', handleAppSuspend); Application.off('resume', handleAppResume); }
Key Notes:
- For Android,
saveState()andrestoreState()work best if the WebView's layout structure doesn't change between suspend and resume. - Enabling cache/DOM storage helps retain form inputs and session data even if a reload is necessary.
- On iOS, we manually save the URL and scroll position since
WKWebView's state restoration requires additional configuration (the above approach is simpler for most cases).
内容的提问来源于stack exchange,提问作者Amit Aisikowitz

