diff options
Diffstat (limited to 'docs/html/guide/tutorials/notepad/notepad-ex3.jd')
-rw-r--r-- | docs/html/guide/tutorials/notepad/notepad-ex3.jd | 125 |
1 files changed, 66 insertions, 59 deletions
diff --git a/docs/html/guide/tutorials/notepad/notepad-ex3.jd b/docs/html/guide/tutorials/notepad/notepad-ex3.jd index 8737280..573500f 100644 --- a/docs/html/guide/tutorials/notepad/notepad-ex3.jd +++ b/docs/html/guide/tutorials/notepad/notepad-ex3.jd @@ -36,7 +36,7 @@ notes.</p> <ol> <li>Remove the code in <code>NoteEdit</code> that parses the title and body - from the extras Bundle. + from the extras Bundle. <p>Instead, we are going to use the <code>DBHelper</code> class to access the notes from the database directly. All we need passed into the NoteEdit Activity is a <code>mRowId</code> (but only if we are editing, if creating we pass @@ -57,7 +57,7 @@ if (body != null) { }</pre> </li> </ol> - + <h2>Step 2</h2> <p>Create a class field for a <code>NotesDbAdapter</code> at the top of the NoteEdit class:</p> @@ -67,11 +67,11 @@ if (body != null) { <pre> mDbHelper = new NotesDbAdapter(this);<br> mDbHelper.open();</pre> - + <h2>Step 3</h2> <p>In <code>NoteEdit</code>, we need to check the <var>savedInstanceState</var> for the -<code>mRowId</code>, in case the note +<code>mRowId</code>, in case the note editing contains a saved state in the Bundle, which we should recover (this would happen if our Activity lost focus and then restarted).</p> <ol> @@ -87,11 +87,11 @@ if (body != null) { </pre> with this: <pre> - mRowId = savedInstanceState != null ? savedInstanceState.getLong(NotesDbAdapter.KEY_ROWID) - : null; + mRowId = (savedInstanceState == null) ? null : + (Long) savedInstanceState.getSerializable(NotesDbAdapter.KEY_ROWID); if (mRowId == null) { - Bundle extras = getIntent().getExtras(); - mRowId = extras != null ? extras.getLong(NotesDbAdapter.KEY_ROWID) + Bundle extras = getIntent().getExtras(); + mRowId = extras != null ? extras.getLong(NotesDbAdapter.KEY_ROWID) : null; } </pre> @@ -100,10 +100,15 @@ if (body != null) { Note the null check for <code>savedInstanceState</code>, and we still need to load up <code>mRowId</code> from the <code>extras</code> Bundle if it is not provided by the <code>savedInstanceState</code>. This is a ternary operator shorthand - to safely either use the value or null if it is not present. + to safely either use the value or null if it is not present. + </li> + <li> + Note the use of <code>Bundle.getSerializable()</code> instead of + <code>Bundle.getLong()</code>. The latter encoding returns a <code>long</code> primitive and + so can not be used to represent the case when <code>mRowId</code> is <code>null</code>. </li> </ol> - + <h2>Step 4</h2> <p>Next, we need to populate the fields based on the <code>mRowId</code> if we @@ -126,38 +131,38 @@ public void onClick(View view) { }</pre> <p>We will take care of storing the updates or new notes in the database ourselves, using the life-cycle methods.</p> - + <p>The whole <code>onCreate()</code> method should now look like this:</p> <pre> super.onCreate(savedInstanceState); - + mDbHelper = new NotesDbAdapter(this); mDbHelper.open(); - + setContentView(R.layout.note_edit); - + mTitleText = (EditText) findViewById(R.id.title); mBodyText = (EditText) findViewById(R.id.body); - + Button confirmButton = (Button) findViewById(R.id.confirm); - -mRowId = savedInstanceState != null ? savedInstanceState.getLong(NotesDbAdapter.KEY_ROWID) - : null; + +mRowId = (savedInstanceState == null) ? null : + (Long) savedInstanceState.getSerializable(NotesDbAdapter.KEY_ROWID); if (mRowId == null) { Bundle extras = getIntent().getExtras(); - mRowId = extras != null ? extras.getLong(NotesDbAdapter.KEY_ROWID) + mRowId = extras != null ? extras.getLong(NotesDbAdapter.KEY_ROWID) : null; } - + populateFields(); - + confirmButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { setResult(RESULT_OK); finish(); } - + });</pre> <h2>Step 6</h2> @@ -180,38 +185,36 @@ is an Android convenience method provided to take care of the Cursor life-cycle. and re-create resources as dictated by the Activity life-cycle, so we don't need to worry about doing that ourselves. After that, we just look up the title and body values from the Cursor and populate the View elements with them.</p> - + <h2>Step 7</h2> - <div class="sidebox" style="border:2px solid #FFFFDD;float:right; - background-color:#FFFFEE;margin-right:0px;margin-bottom:.5em; - margin-top:1em;padding:0em;width:240px;"> - <h2 style="border:0;font-size:12px;padding:.5em .5em .5em 1em;margin:0; - background-color:#FFFFDD;">Why handling life-cycle events is important</h2> - <p style="padding-left:.5em;font-size:12px;margin:0; - padding:.0em .5em .5em 1em;">If you are used to always having control in your applications, you - might not understand why all this life-cycle work is necessary. The reason - is that in Android, you are not in control of your Activity, the - operating system is!</p> - <p style="padding-left:.5em;font-size:12px;margin:0; - padding:.0em .5em .5em 1em;">As we have already seen, the Android model is based around activities - calling each other. When one Activity calls another, the current Activity - is paused at the very least, and may be killed altogether if the - system starts to run low on resources. If this happens, your Activity will - have to store enough state to come back up later, preferably in the same - state it was in when it was killed.</p> - <p style="padding-left:.5em;font-size:12px;margin:0;padding:.0em .5em .5em 1em;"> - Android has a <a href="{@docRoot}guide/topics/fundamentals.html#lcycles">well-defined life cycle</a>. - Lifecycle events can happen even if you are not handing off control to - another Activity explicitly. For example, perhaps a call comes in to the - handset. If this happens, and your Activity is running, it will be swapped - out while the call Activity takes over.</p> - </div> - -<p>Still in the <code>NoteEdit</code> class, we now override the methods - <code>onSaveInstanceState()</code>, <code>onPause()</code> and - <code>onResume()</code>. These are our life-cycle methods + <div class="sidebox-wrapper"> + <div class="sidebox"> + <h2>Why handling life-cycle events is important</h2> + <p>If you are used to always having control in your applications, you + might not understand why all this life-cycle work is necessary. The reason + is that in Android, you are not in control of your Activity, the + operating system is!</p> + <p>As we have already seen, the Android model is based around activities + calling each other. When one Activity calls another, the current Activity + is paused at the very least, and may be killed altogether if the + system starts to run low on resources. If this happens, your Activity will + have to store enough state to come back up later, preferably in the same + state it was in when it was killed.</p> + <p> + Android has a <a href="{@docRoot}guide/topics/fundamentals.html#lcycles">well-defined life +cycle</a>. + Lifecycle events can happen even if you are not handing off control to + another Activity explicitly. For example, perhaps a call comes in to the + handset. If this happens, and your Activity is running, it will be swapped + out while the call Activity takes over.</p> + </div> + </div> + +<p>Still in the <code>NoteEdit</code> class, we now override the methods + <code>onSaveInstanceState()</code>, <code>onPause()</code> and + <code>onResume()</code>. These are our life-cycle methods (along with <code>onCreate()</code> which we already have).</p> <p><code>onSaveInstanceState()</code> is called by Android if the @@ -241,8 +244,10 @@ and populate the View elements with them.</p> @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); - outState.putLong(NotesDbAdapter.KEY_ROWID, mRowId); + saveState(); + outState.putSerializable(NotesDbAdapter.KEY_ROWID, mRowId); }</pre> + <p>We'll define <code>saveState()</code> next.</p> </li> <li><code> onPause()</code>: @@ -252,7 +257,6 @@ and populate the View elements with them.</p> super.onPause(); saveState(); }</pre> - <p>We'll define <code>saveState()</code> next.</p> </li> <li><code> onResume()</code>: @@ -264,6 +268,10 @@ and populate the View elements with them.</p> }</pre> </li> </ol> +<p>Note that <code>saveState()</code> must be called in both <code>onSaveInstanceState()</code> +and <code>onPause()</code> to ensure that the data is saved. This is because there is no +guarantee that <code>onSaveInstanceState()</code> will be called and because when it <em>is</em> +called, it is called before <code>onPause()</code>.</p> <h2 style="clear:right;">Step 8</h2> @@ -301,19 +309,18 @@ database.</p> necessary. The resulting method should look like this:</p> <pre> @Override -protected void onActivityResult(int requestCode, int resultCode, - Intent intent) { +protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); fillData(); }</pre> <p>Because the other class now does the work, all this has to do is refresh the data.</p> - + <h2>Step 10</h2> <p>Also remove the lines which set the title and body from the - <code>onListItemClick()</code> method (again they are no longer needed, + <code>onListItemClick()</code> method (again they are no longer needed, only the <code>mRowId</code> is):</p> <pre> Cursor c = mNotesCursor; @@ -344,13 +351,13 @@ so that all that should be left in that method is: other occurrences of <code>mNotesCursor</code> in your <code>fillData()</code> method. </ol> <p> -Run it! (use <em>Run As -> Android Application</em> on the project right +Run it! (use <em>Run As -> Android Application</em> on the project right click menu again)</p> <h2>Solution and Next Steps</h2> <p>You can see the solution to this exercise in <code>Notepadv3Solution</code> -from +from the zip file to compare with your own.</p> <p> When you are ready, move on to the <a href="notepad-extra-credit.html">Tutorial |