- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / common / extensions / docs / templates / articles / app_codelab6_lifecycle.html
1 <h1 id="lab_6_lifecycle">Manage App Lifecycle</h1>
2
3 <p>Like everything in this world, apps have a lifecycle.  They are installed, launched, restarted, suspended when the system needs to free up resources and uninstalled.  This lab will show you the basics of the Chrome app lifecycle and how its heart, the event page (aka background script), is used.</p>
4
5 <h2 id="the_event_page">The event page</h2>
6
7 <p>The event page is one of the most important pieces of a Chrome app. It&#39;s responsible for what gets launched, when, and how.
8 For example, if your app is an instant messenger, you might want your event page to only show a UI when there is a new notification.</p>
9
10 <p>For simpler apps, the event page listens to the app lifecycle events and reacts appropriately.
11 There are two important lifecycle events, $ref:app.runtime.onLaunched and $ref:app.runtime.onRestarted.</p>
12
13 <h2 id="the_onlaunched">The onLaunched event</h2>
14
15 <p>The $ref:app.runtime.onLaunched event is the most important event.
16 It fires when the user clicks on your app&#39;s icon with the intent of launching it.
17 For most simpler apps,
18 the event page will listen for this event and open a window when it fires.
19 See
20 <a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab6_lifecycle/angularjs/main.js">AngularJS main.js</a> or
21 <a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab6_lifecycle/javascript/main.js">JavaScript main.js</a>
22 for the most common usage.</p>
23
24 <h3 id="windows_with_ids">Windows with IDs</h3>
25
26 <p>The $ref:app.window.create method can associate an ID to the window being opened. Currently, the most interesting use for this is to restore a window&#39;s width, height and location and its associated Developer Tools window, if opened, when the app is launched. </p>
27
28 <p>Execute your app as it is now, move and resize the window,
29 close and restart it.
30 The app will reopen in the original location, right?
31 Now add a property <code>id</code> to the event page,
32 <a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab6_lifecycle/angularjs/main.js">Angular main.js</a> or
33 <a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab6_lifecycle/javascript/main.js">JavaScript main.js</a>,
34 reload the app and test again:</p>
35
36 <pre data-filename="main.js">
37 chrome.app.runtime.onLaunched.addListener(function() {
38     chrome.app.window.create(&#39;index.html&#39;,
39       {id: &#39;mainwindow&#39;, bounds: {width: 500, height: 309} });
40   });
41 </pre>
42
43 <p>If your application requires, you can open more than one window.</p>
44
45 <h2 id="the_onrestarted_event">The onRestarted event</h2>
46
47 <p>The $ref:app.runtime.onRestarted event is not as essential as <code>onLaunched</code>,
48 but it might be relevant to certain types of apps.
49 This event is executed when the app is restarted, for example,
50 when Chrome quits, restarts, and the app is launched again.
51 You can use this event to restore a transient state.</p>
52
53 <p>For example, if your app has a form with several fields,
54 you won&#39;t always want to save the partial form while the user is typing.
55 If the user quits the app on purpose, she might not be interested keeping the partial data.
56 If the Chrome runtime restarted for some reason other than by a user&#39;s intention,
57 the user will want that data when the app is restarted.</p>
58
59 <p>Let&#39;s change our code to save the Todo input field in $ref:storage as the user types,
60 only restoring it if the <code>onRestarted</code> event is triggered.</p>
61
62 <p class="note"><b>Note:</b>
63 We learned about <code>chrome.storage.sync</code> before, but
64 <a href="storage.html#using-sync">chrome.storage.local</a>
65 wasn&#39;t mentioned until now.
66 Both have exactly the same syntax,
67 but the semantics of <code>chrome.storage.local</code> is, as the name says, completely local.
68 There&#39;s no attempt to synchronize or to save the data in the cloud.</p>
69
70 <h3 id="event-page">Update event page</h3>
71
72 <p>Update the event page to include the
73 <code>onLaunched</code> and <code>onRestarted</code> events.
74 Events are handled the same in
75 <a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab6_lifecycle/angularjs/main.js">AngularJS main.js</a> and
76 <a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab6_lifecycle/javascript/main.js">JavaScript main.js</a>:
77 </p>
78
79 <pre data-filename="main.js">
80 chrome.app.runtime.onLaunched.addListener(function() {
81   // normal launch initiated by the user, let&#39;s start clean.
82   // note that this is not related to the persistent state, which is
83   // appropriately handled in the window code.
84   runApp(false);
85 });
86
87 chrome.app.runtime.onRestarted.addListener(function() {
88   // if restarted, try to get the transient saved state
89   runApp(true);
90 });
91
92 function runApp(readInitialState) {
93   chrome.app.window.create(&#39;index.html&#39;,
94     {id: &#39;mainwindow&#39;, bounds: {width: 500, height: 309} },
95     // the create callback gets a reference to the AppWindow obj 
96     function(win) {
97       // when the callback is executed, the DOM is loaded but no script was
98       // loaded yet. So, let&#39;s attach to the load event.
99       win.contentWindow.addEventListener(&#39;load&#39;, function() {
100         if (readInitialState) {
101           win.contentWindow.setInitialState();
102         } else {
103           win.contentWindow.clearInitialState();
104         }
105       });
106     });
107 }
108 </pre>
109
110 <h3 id="controller">Update controller</h3>
111
112 <p>Add to existing
113 <a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab6_lifecycle/angularjs/controller.js">AngularJS controller.js</a> or
114 <a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab6_lifecycle/javascript/controller.js">JavaScript controller.js</a>:
115 </p>
116
117 <tabs data-group="source">
118
119   <header tabindex="0" data-value="angular">Angular</header>
120   <header tabindex="0" data-value="js">JavaScript</header>
121   
122   <content>
123     <pre data-filename="controller.js">
124 var newTodoInput = null;
125
126 var clearInitialState = function() {
127   chrome.storage.local.set({&#39;newtodo&#39;: null});
128 }
129
130 var setInitialState = function() {
131   chrome.storage.local.get(&#39;newtodo&#39;, function(data) {
132     if (newTodoInput &amp;&amp; data &amp;&amp; data.newtodo) {
133       newTodoInput.value = data.newtodo;
134       newTodoInput.focus();
135     }
136   });
137 }
138
139 window.addEventListener(&#39;load&#39;, function() {
140   var saveTransientState = function() {
141     chrome.storage.local.set({&#39;newtodo&#39;: newTodoInput.value});
142   };
143   newTodoInput = document.querySelector(&#39;input[type=&quot;text&quot;]&#39;);
144   newTodoInput.addEventListener(&#39;keypress&#39; , function() {
145     saveTransientState();<br>
146   })
147 })
148     </pre>
149   </content>
150   <content>
151     <pre data-filename="controller.js">
152   var newTodoInput = document.querySelector('input[type="text"]');
153  
154   window.clearInitialState = function() {
155     chrome.storage.local.set({'newtodo': null});
156   }
157    
158   window.setInitialState = function() {
159     chrome.storage.local.get('newtodo', function(data) {
160       if (newTodoInput && data && data.newtodo) {
161         newTodoInput.value = data.newtodo;
162         newTodoInput.focus();
163       }
164     });
165   };
166      
167   var saveTransientState = function() {
168     chrome.storage.local.set({'newtodo': newTodoInput.value});
169   };
170
171   newTodoInput.addEventListener('keypress' , function() {
172     saveTransientState();    
173   })
174     </pre>
175
176 </tabs>
177
178 <h3 id="results">Check the results</h3>
179
180 <p>Save the changes by reloading the app:
181 open the app, right-click and select Reload.</p>
182
183 <p>If Chrome and the app shuts down for any reason (other than a user-gesture),
184 the <code>onRestarted</code> event is fired.
185 Any text entered in the input field (but not yet saved as a Todo item)
186 will reappear when Chrome and the app are reopened.</p>
187
188 <p>If you get stuck and want to see the app in action,
189 go to <code>chrome://extensions</code>,
190 load the unpacked
191 <a href="https://github.com/GoogleChrome/chrome-app-codelab/tree/master/lab6_lifecycle/angularjs">AngularJS app</a> or
192 <a href="https://github.com/GoogleChrome/chrome-app-codelab/tree/master/lab6_lifecycle/javascript">JavaScript app</a>,
193 and launch the app from a new tab.</p>
194
195 <h2 id="takeaways_">Takeaways</h2>
196
197 <ul>
198 <li>The event page may continue to run even when your windows are closed;
199 you can move logic that is shared amoung windows to the event page.</li>
200 </ul>
201
202 <h2 id="you_should_also_read">You should also read</h2>
203
204 <p><a href="app_lifecycle.html">Manage App Lifecycle</a> tutorial</p>
205
206 <h2 id="what_39_s_next_">What's next?</h2>
207
208 <p>In <a href="app_codelab7_useridentification.html">6 - Access User's Data</a>,
209 you will learn how to identify users and use OAuth2.0 to access Google and other third party services.</p>
210
211 <p class="note"><b>Note:</b>
212 The next chapter covers a still experimental API.
213 If you don't want to play with experimental APIs, feel free to skip it - the
214 rest of the codelab is independent from it.
215 </p>