该页面翻译自 Google Chrome Extensions 与 Google Chrome Apps。除非特别说明,该页面的内容遵循 Creative Commons Attribution 3.0 License,代码示例遵循 BSD License。
与世界上的所有事物一样,应用也有生命周期。它们会安装、运行、重新启动,在系统需要释放资源时会暂停,还会被卸载。该实验将向您展示 Chrome 应用生命周期的基础知识,以及它的核心——事件页面(即后台脚本)是如何使用的。
事件页面是 Chrome 应用最重要的部分之一,它负责确定运行的内容、时间与方式。例如,如果您的应用是一个即时通信工具,您可能希望您的事件页面在有新消息时才显示用户界面。
对于较小的应用,事件页面监听应用生命周期事件,并作出合理的反应。有两个重要的生命周期事件,包括 app.runtime.onLaunched 和 app.runtime.onRestarted。
app.runtime.onLaunched 事件是最重要的事件,当用户为了执行而单击您的应用图标时产生。对于大多数较简单的应用来说,事件页面应该监听该事件并在它产生时打开一个窗口。有关这一常见用法,请参见我们的 AngularJS main.js 或 JavaScript main.js。
app.window.create 方法可以将标识符和打开的窗口关联。目前,最有意思的用途是在应用执行时恢复窗口的宽度、高度和位置,以及与之关联的开发者工具窗口(如果打开的话)。
执行您现在的应用,移动并调整窗口的大小,关闭后在重新启动,应用还是会在原来的位置重新打开,是吗?现在在
AngularJS main.js 或
JavaScript main.js
中添加一个 id 属性,重新加载应用并再次测试:
chrome.app.runtime.onLaunched.addListener(function() {
chrome.app.window.create('index.html',
{id: 'mainwindow', bounds: {width: 500, height: 309} });
});
如果您的应用程序需要的话,您可以打开一个以上的窗口。
app.runtime.onRestarted 事件不像 onLaunched
那样重要,但是它可能和某些类型的应用相关。当应用重新启动时,例如当 Chrome
浏览器退出、重新启动,再次运行应用时,将会执行该事件。您可以利用该事件恢复临时的状态。
例如,如果您的应用有一个表单,包含多个字段,您不会在用户输入时就保存部分的表单。如果用户特意退出您的应用,他们不一定希望保留这部分数据。如果 Chrome 运行时环境由于用户意图以外的原因重新启动,在应用重新启动时用户可能还需要这些数据。
让我们更改我们的代码,将待办事项输入字段保存在 storage
中,只有在 onRestarted 事件触发时才恢复它。
注意:我们之前学习了
chrome.storage.sync,但是直到现在才提到了
chrome.storage.local。它们有完全相同的语法,但是正如它的名称所述,chrome.storage.local
的含义完全是本地的,而不会尝试同步或者将数据保存到云端。
更新事件页面,包含
onLaunched 和 onRestarted
事件。在
AngularJS main.js 中
JavaScript main.js
处理事件的方式相同:
chrome.app.runtime.onLaunched.addListener(function() {
// normal launch initiated by the user, let's start clean.
// note that this is not related to the persistent state, which is
// appropriately handled in the window code.
runApp(false);
});
chrome.app.runtime.onRestarted.addListener(function() {
// if restarted, try to get the transient saved state
runApp(true);
});
function runApp(readInitialState) {
chrome.app.window.create('index.html',
{id: 'mainwindow', bounds: {width: 500, height: 309} },
// the create callback gets a reference to the AppWindow obj
function(win) {
// when the callback is executed, the DOM is loaded but no script was
// loaded yet. So, let's attach to the load event.
win.contentWindow.addEventListener('load', function() {
if (readInitialState) {
win.contentWindow.setInitialState();
} else {
win.contentWindow.clearInitialState();
}
});
});
}
添加到现有的 AngularJS controller.js 或 JavaScript controller.js:
var newTodoInput = null;
var clearInitialState = function() {
chrome.storage.local.set({'newtodo': null});
}
var setInitialState = function() {
chrome.storage.local.get('newtodo', function(data) {
if (newTodoInput && data && data.newtodo) {
newTodoInput.value = data.newtodo;
newTodoInput.focus();
}
});
}
window.addEventListener('load', function() {
var saveTransientState = function() {
chrome.storage.local.set({'newtodo': newTodoInput.value});
};
newTodoInput = document.querySelector('input[type="text"]');
newTodoInput.addEventListener('keypress' , function() {
saveTransientState();
})
})
var newTodoInput = document.querySelector('input[type="text"]');
window.clearInitialState = function() {
chrome.storage.local.set({'newtodo': null});
}
window.setInitialState = function() {
chrome.storage.local.get('newtodo', function(data) {
if (newTodoInput && data && data.newtodo) {
newTodoInput.value = data.newtodo;
newTodoInput.focus();
}
});
};
var saveTransientState = function() {
chrome.storage.local.set({'newtodo': newTodoInput.value});
};
newTodoInput.addEventListener('keypress' , function() {
saveTransientState();
})
重新加载应用,检查结果:打开应用,单击右键并选择“重新加载应用”。
如果 Chrome 浏览器和应用由于任何原因(而不是用户操作)关闭,则会产生
onRestarted 事件,输入字段中键入的文本(但是还没有保存为待办事项)会在
Chrome 浏览器和应用重新打开时再次出现。
如果您遇到了困难,希望立刻看到应用,请进入
chrome://extensions,载入未打包的
AngularJS 应用 或
JavaScript 应用,并从新标签页中运行应用。
在 6 - 访问用户数据中,您将学习如何认证用户以及如何使用 OAuth2.0 访问 Google 和其他第三方服务。
注意:下一章涉及到的 API 仍然是实验性的,如果您不想尝试实验性 API,您可以跳过,代码实验室的剩余部分不依赖它。