问题
I have a simple UWP application built in HTML/JS/CSS. It is essentially a website, that loads some data into webview and so on, nothing out of ordinary.
What I struggle with is the application lifecycle and its "resuming" state, where is the application has been already running, and user opens the application again, then the whole application is re-rendered, all the html+js gets to run again which is causing basically a reload (just like via F5). How do I prevent it?
Here is the very basic main.js file, and please note the line where I compare the previous execution state with the application execution state "running". I reckon there is something I should do in order to prevent the reload of my app (or re-render in other words), so it doesn't go through the initialization process again. It just looks bad as all the resources are being loaded again.
(function () {
"use strict";
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
var isFirstActivation = true;
app.onactivated = function (args) {
if (args.detail.kind === activation.ActivationKind.voiceCommand) {
// TODO: Handle relevant ActivationKinds. For example, if your app can be started by voice commands,
// this is a good place to decide whether to populate an input field or choose a different initial view.
}
else if (args.detail.kind === activation.ActivationKind.launch) {
// A Launch activation happens when the user launches your app via the tile
// or invokes a toast notification by clicking or tapping on the body.
if (args.detail.arguments) {
// TODO: If the app supports toasts, use this value from the toast payload to determine where in the app
// to take the user in response to them invoking a toast notification.
}
else if (args.detail.previousExecutionState === activation.ApplicationExecutionState.terminated) {
// TODO: This application had been suspended and was then terminated to reclaim memory.
// To create a smooth user experience, restore application state here so that it looks like the app never stopped running.
// Note: You may want to record the time when the app was last suspended and only restore state if they've returned after a short period.
}
else if (args.detail.previousExecutionState === activation.ApplicationExecutionState.running) {
isFirstActivation = false;
}
}
if (!args.detail.prelaunchActivated) {
// TODO: If prelaunchActivated were true, it would mean the app was prelaunched in the background as an optimization.
// In that case it would be suspended shortly thereafter.
// Any long-running operations (like expensive network or disk I/O) or changes to user state which occur at launch
// should be done here (to avoid doing them in the prelaunch case).
// Alternatively, this work can be done in a resume or visibilitychanged handler.
}
if (isFirstActivation) {
// TODO: The app was activated and had not been running. Do general startup initialization here.
document.addEventListener("visibilitychange", onVisibilityChanged);
args.setPromise(WinJS.UI.processAll().then(function(){ WinJS.UI.enableAnimations();}));
}
isFirstActivation = false;
};
function onVisibilityChanged(args) {
if (!document.hidden) {
// TODO: The app just became visible. This may be a good time to refresh the view.
}
}
app.oncheckpoint = function (args) {
// TODO: This application is about to be suspended. Save any state that needs to persist across suspensions here.
// You might use the WinJS.Application.sessionState object, which is automatically saved and restored across suspension.
// If you need to complete an asynchronous operation before your application is suspended, call args.setPromise().
};
app.start();
})();
回答1:
Ok, so after some time of debugging and rewriting the application front and back, I've realized that the culprit here was the "StartPage" in the application manifest.
The problem with application being "re-loaded" even if it was in the running state before was caused by the "app.Start()" being triggered each time after user re-opened the application. But samples from the UWP samples kit didn't suffer from this behavior, and I've noticed that the "app.Start()" is being triggered only once, when the application was actually started. Each subsequent opening didn't get to that point anymore (to "app.Start()") like in my app.
Previously, I had this value to set StartPage="ms-appx-web:///index.html" due to Content Security Policy problem. But comparing this value with the samples, they used "StartPage=index.html" made me think that might be the problem and I was right. It took me couple of hours to make sure I don't get any content security policy related errors (inline scripts replaced) but it eventually worked.
I can't explain why the "StartPage='ms-appx-web:///index.html'" causes the application to be re-started each time, whereas "StartPage='index.html'" is correctly maintaining its state, but it did resolve my problem.
来源:https://stackoverflow.com/questions/39436947/windows-uwp-application-lifecycle-how-to-prevent-reload-in-js-html-css-app