Windows 8 Javascript 应用 activation/launch 延期
Windows 8 Javascript app activation/launch deferral
所以目前在我正在编码的 windows 8 WinJS 应用程序中,我试图让 xml 文件的加载发生在应用程序启动序列中,而启动画面仍在显示,因为主页加载时需要此 xmldoc 元素,如果没有它,主页加载将失败。
这是我在default.js中的启动顺序:
(function () {
"use strict";
var activation = Windows.ApplicationModel.Activation;
var app = WinJS.Application;
var nav = WinJS.Navigation;
var sched = WinJS.Utilities.Scheduler;
var ui = WinJS.UI;
app.addEventListener("activated", function (args) {
if (args.detail.kind === activation.ActivationKind.launch) {
if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
// TODO: This application has been newly launched. Initialize
// your application here.
console.log("Newly Launched!");
var localSettings = Windows.Storage.ApplicationData.current.localSettings;
WinJS.Namespace.define("MyGlobals", { localSettings: localSettings });
// APP RUN TYPE CHECK AND SEQUENCE (FIRST RUN / NOT FIRST RUN):
if (MyGlobals.localSettings.values['firstRunCompleted']) {
console.log("NOT FIRST RUN!");
// CACHE VERSION CHECK. IF APP HAS BEEN UPDATED, INITIATE NEWLY ADDED CACHE VALUES HERE:
} else {
console.log("FIRST RUN!")
MyGlobals.localSettings.values['firstRunCompleted'] = true;
};
//loadXML(); have tried many things with this. doesn't work.
} else {
// TODO: This application has been reactivated from suspension.
// Restore application state here.
var currentVolume = app.sessionState.currentVolume;
if (currentVolume) {
console.log("RESTORE FROM SUSPENSION");
console.log(currentVolume);
};
}
nav.history = app.sessionState.history || {};
nav.history.current.initialPlaceholder = true;
// Optimize the load of the application and while the splash screen is shown, execute high priority scheduled work.
ui.disableAnimations();
var p = ui.processAll().then(function () {
return nav.navigate(nav.location || Application.navigator.home, nav.state);
}).then(function () {
return sched.requestDrain(sched.Priority.aboveNormal + 1);
}).then(function () {
ui.enableAnimations();
});
args.setPromise(p);
args.setPromise(WinJS.UI.processAll().then(function completed() {
loadSavedColour();
// Populate Settings pane and tie commands to Settings flyouts.
WinJS.Application.onsettings = function (e) {
e.detail.applicationcommands = {
"helpDiv": { href: "html/Help.html", title: WinJS.Resources.getString("settings_help").value },
"aboutDiv": { href: "html/About.html", title: WinJS.Resources.getString("settings_about").value },
"settingsDiv": { href: "html/Settings.html", title: WinJS.Resources.getString("settings_settings").value },
};
WinJS.UI.SettingsFlyout.populateSettings(e);
}
如您所见,我在 "loadXML()" 的注释行中看到了我需要加载 XML() 函数的地方。
这是我的 loadXML() 函数:
function loadXML() {
Windows.ApplicationModel.Package.current.installedLocation.getFolderAsync("foldername").then(function (externalDtdFolder) {
externalDtdFolder.getFileAsync(MyGlobals.localSettings.values['currentBook']).done(function (file) {
Windows.Data.Xml.Dom.XmlDocument.loadFromFileAsync(file).then(function (doc) {
WinJS.Namespace.define("MyGlobals", {
xmlDoc: doc,
});
})
})
});
};
(loadXML是一个工作函数,在其他场景下也工作)
但是,问题是在加载 XML 函数完成之前,应用启动画面消失,然后加载下一个 home.html 主页,这会启动伴随的 home.js ,它有一个函数需要 loadXML 应该创建的 MyGlobals.xmlDoc 对象。这会立即使应用程序崩溃,因为 MyGlobals.xmlDoc 是 undefined/null。
我曾经通过 运行 loadXML in home.js 直接为 home.html 页面运行此应用程序,但在那种情况下,每次都会重新加载 XML 文档导航到页面,浪费时间和资源。因此,我正在尝试将 xml 文档加载到应用 startup/initialization 中。
非常感谢!
我相信您需要做的是延长启动画面,让您的应用有更多时间进行初始化 UI。对于您的场景,它正在加载 xml.
我会建议您阅读 How to extend the splash screen (HTML)。主要思想是在激活事件中显示一个扩展的启动画面(你可以使用与默认画面相同的图像),然后调用你的 loadXML。
loadXML
具有异步功能,您需要处理它。
您不应该期望 loadFromFileAsync
(或任何其他异步函数)在 returns 到调用者之前已经完成。如果您的代码不等待,您会发现 MyGlobals.xmlDoc
值不会在您需要时设置。
我在下面对其进行了重命名,以使其行为更加准确。最大的变化是它 returns 一个 Promise
,调用者可以使用它来正确等待 Xml 文档被加载。这个 Promise
可以与其他 Promise
一起使用,以在您愿意的情况下等待多个条件(或者在其他异步工作的情况下)。
function loadXMLAsync() {
return new WinJS.Promise(function (complete, error, progress) {
var localSettings = MyGlobals.localSettings.values;
var installedLocation = Windows.ApplicationModel.Package.current.installedLocation;
installedLocation.getFolderAsync("foldername").then(function (externalDtdFolder) {
externalDtdFolder.getFileAsync(values['currentBook']).done(function (file) {
Windows.Data.Xml.Dom.XmlDocument.loadFromFileAsync(file).then(function (doc) {
complete(doc);
});
});
});
});
};
然后,使用中:
loadXmlAsync().then(function(doc) {
WinJS.Namespace.define("MyGlobals", {
xmlDoc: doc,
});
// and any other code that should wait until this has completed
});
上面的代码没有处理错误。
除了其他注释之外,您真正需要做的是将来自 loadXml 的承诺包含在您传递给 args.setPromise 的内容中。如您所知,setPromise 是一种告诉应用程序加载器在移除启动画面之前等待该承诺实现的方法。但是,在您的代码中,您多次调用 setPromise 。您应该做的是将您关心的所有承诺(动画、loadXml 和设置加载)与 WinJS.Promise.join 结合起来,这样您就可以获得一个承诺,然后等待所有其他三个承诺,当 那个一个完成了,然后移除闪屏。
如果整个加载过程最终花费的时间太长,Alan 关于扩展启动画面的建议会很有帮助,因为扩展启动画面可以让您完全控制正在发生的事情以及何时发生到主页的转换。
所以目前在我正在编码的 windows 8 WinJS 应用程序中,我试图让 xml 文件的加载发生在应用程序启动序列中,而启动画面仍在显示,因为主页加载时需要此 xmldoc 元素,如果没有它,主页加载将失败。
这是我在default.js中的启动顺序:
(function () {
"use strict";
var activation = Windows.ApplicationModel.Activation;
var app = WinJS.Application;
var nav = WinJS.Navigation;
var sched = WinJS.Utilities.Scheduler;
var ui = WinJS.UI;
app.addEventListener("activated", function (args) {
if (args.detail.kind === activation.ActivationKind.launch) {
if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
// TODO: This application has been newly launched. Initialize
// your application here.
console.log("Newly Launched!");
var localSettings = Windows.Storage.ApplicationData.current.localSettings;
WinJS.Namespace.define("MyGlobals", { localSettings: localSettings });
// APP RUN TYPE CHECK AND SEQUENCE (FIRST RUN / NOT FIRST RUN):
if (MyGlobals.localSettings.values['firstRunCompleted']) {
console.log("NOT FIRST RUN!");
// CACHE VERSION CHECK. IF APP HAS BEEN UPDATED, INITIATE NEWLY ADDED CACHE VALUES HERE:
} else {
console.log("FIRST RUN!")
MyGlobals.localSettings.values['firstRunCompleted'] = true;
};
//loadXML(); have tried many things with this. doesn't work.
} else {
// TODO: This application has been reactivated from suspension.
// Restore application state here.
var currentVolume = app.sessionState.currentVolume;
if (currentVolume) {
console.log("RESTORE FROM SUSPENSION");
console.log(currentVolume);
};
}
nav.history = app.sessionState.history || {};
nav.history.current.initialPlaceholder = true;
// Optimize the load of the application and while the splash screen is shown, execute high priority scheduled work.
ui.disableAnimations();
var p = ui.processAll().then(function () {
return nav.navigate(nav.location || Application.navigator.home, nav.state);
}).then(function () {
return sched.requestDrain(sched.Priority.aboveNormal + 1);
}).then(function () {
ui.enableAnimations();
});
args.setPromise(p);
args.setPromise(WinJS.UI.processAll().then(function completed() {
loadSavedColour();
// Populate Settings pane and tie commands to Settings flyouts.
WinJS.Application.onsettings = function (e) {
e.detail.applicationcommands = {
"helpDiv": { href: "html/Help.html", title: WinJS.Resources.getString("settings_help").value },
"aboutDiv": { href: "html/About.html", title: WinJS.Resources.getString("settings_about").value },
"settingsDiv": { href: "html/Settings.html", title: WinJS.Resources.getString("settings_settings").value },
};
WinJS.UI.SettingsFlyout.populateSettings(e);
}
如您所见,我在 "loadXML()" 的注释行中看到了我需要加载 XML() 函数的地方。 这是我的 loadXML() 函数:
function loadXML() {
Windows.ApplicationModel.Package.current.installedLocation.getFolderAsync("foldername").then(function (externalDtdFolder) {
externalDtdFolder.getFileAsync(MyGlobals.localSettings.values['currentBook']).done(function (file) {
Windows.Data.Xml.Dom.XmlDocument.loadFromFileAsync(file).then(function (doc) {
WinJS.Namespace.define("MyGlobals", {
xmlDoc: doc,
});
})
})
});
};
(loadXML是一个工作函数,在其他场景下也工作)
但是,问题是在加载 XML 函数完成之前,应用启动画面消失,然后加载下一个 home.html 主页,这会启动伴随的 home.js ,它有一个函数需要 loadXML 应该创建的 MyGlobals.xmlDoc 对象。这会立即使应用程序崩溃,因为 MyGlobals.xmlDoc 是 undefined/null。 我曾经通过 运行 loadXML in home.js 直接为 home.html 页面运行此应用程序,但在那种情况下,每次都会重新加载 XML 文档导航到页面,浪费时间和资源。因此,我正在尝试将 xml 文档加载到应用 startup/initialization 中。 非常感谢!
我相信您需要做的是延长启动画面,让您的应用有更多时间进行初始化 UI。对于您的场景,它正在加载 xml.
我会建议您阅读 How to extend the splash screen (HTML)。主要思想是在激活事件中显示一个扩展的启动画面(你可以使用与默认画面相同的图像),然后调用你的 loadXML。
loadXML
具有异步功能,您需要处理它。
您不应该期望 loadFromFileAsync
(或任何其他异步函数)在 returns 到调用者之前已经完成。如果您的代码不等待,您会发现 MyGlobals.xmlDoc
值不会在您需要时设置。
我在下面对其进行了重命名,以使其行为更加准确。最大的变化是它 returns 一个 Promise
,调用者可以使用它来正确等待 Xml 文档被加载。这个 Promise
可以与其他 Promise
一起使用,以在您愿意的情况下等待多个条件(或者在其他异步工作的情况下)。
function loadXMLAsync() {
return new WinJS.Promise(function (complete, error, progress) {
var localSettings = MyGlobals.localSettings.values;
var installedLocation = Windows.ApplicationModel.Package.current.installedLocation;
installedLocation.getFolderAsync("foldername").then(function (externalDtdFolder) {
externalDtdFolder.getFileAsync(values['currentBook']).done(function (file) {
Windows.Data.Xml.Dom.XmlDocument.loadFromFileAsync(file).then(function (doc) {
complete(doc);
});
});
});
});
};
然后,使用中:
loadXmlAsync().then(function(doc) {
WinJS.Namespace.define("MyGlobals", {
xmlDoc: doc,
});
// and any other code that should wait until this has completed
});
上面的代码没有处理错误。
除了其他注释之外,您真正需要做的是将来自 loadXml 的承诺包含在您传递给 args.setPromise 的内容中。如您所知,setPromise 是一种告诉应用程序加载器在移除启动画面之前等待该承诺实现的方法。但是,在您的代码中,您多次调用 setPromise 。您应该做的是将您关心的所有承诺(动画、loadXml 和设置加载)与 WinJS.Promise.join 结合起来,这样您就可以获得一个承诺,然后等待所有其他三个承诺,当 那个一个完成了,然后移除闪屏。
如果整个加载过程最终花费的时间太长,Alan 关于扩展启动画面的建议会很有帮助,因为扩展启动画面可以让您完全控制正在发生的事情以及何时发生到主页的转换。