管理应用的生命周期
与世界上的所有事物一样,应用也有生命周期。它们会安装、运行、重新启动,在系统需要释放资源时会暂停,还会被卸载。该实验将向您展示 Chrome 应用生命周期的基础知识,以及它的核心——事件页面(即后台脚本)是如何使用的。
事件页面
事件页面是 Chrome 应用最重要的部分之一,它负责确定运行的内容、时间与方式。例如,如果您的应用是一个即时通信工具,您可能希望您的事件页面在有新消息时才显示用户界面。
对于较小的应用,事件页面监听应用生命周期事件,并作出合理的反应。有两个重要的生命周期事件,包括 app.runtime.onLaunched 和 app.runtime.onRestarted。
onLaunched 事件
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} }); });
如果您的应用程序需要的话,您可以打开一个以上的窗口。
onRestarted 事件
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,您可以跳过,代码实验室的剩余部分不依赖它。