I asked on the android-developers list about this (before I knew of
the android-beginners list), and got no response. I really frown on
example and tutorial code with bugs. If you're trying to show "this is
how you do it", I think you should actually show the right way to do
it. This led to a crash in an app I'm developing when I assumed the
code was, y'know, correct.
Anyway, I'm contributing a solution here so others can hopefully not
be led too far astray. At least it forced me to get more familiar with
the debugger!
The problem is in "NoteEdit.java". Even in the final version of the
app, if this activity gets relaunched - e.g. by an orientation change
- it'll crash. This is because the logic involved in saving and
restoring state is faulty. Changes need to be made in onCreate() and
onSaveInstanceState().
First, look at onSaveInstanceState(). If you've got an empty note
(say, the activity was launched with "Add Note"), then mRowId is null,
and trying to do an outState.putLong() will give you a fresh, exciting
NullPointerException. But if we don't save anything... when we try to
restore the value in onCreate(), we'll get the value 0L, which can be
a valid row ID! So instead, I do the following:
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// It's a no-no to try to save a null! So instead we save an
invalid row id...
if (mRowId != null) {
outState.putLong(NotesDbAdapter.KEY_ROWID, mRowId);
} else {
outState.putLong(NotesDbAdapter.KEY_ROWID, -1L);
}
}
Note: I'm not 100% sure that "-1" is an invalid row ID - SQLite
apparently *can* support negative row IDs - but so far in my limited
testing it seems to be the case that Android won't generate such IDs
spontaneously. You have go out of your way to make them. If this is
not the case, please let me know!
Now, back up in onCreate(), we modify our initialization as follows.
(I've gotten rid of the '?:' construct because it confuses the Eclipse
debugger, which bounces around to various unrelated lines if you try
to step through it.)
// First, see if we have saved state we should use
if (savedInstanceState != null) {
mRowId = savedInstanceState.getLong(NotesDbAdapter.KEY_ROWID);
// Did we save an invalid row id?
if (mRowId == -1L) {
// Make sure we don't try to use the invalid row!
mRowId = null;
}
} else {
mRowId = null;
}
if (mRowId == null) {
// Must not have been any saved state. Okay, were we launched
with
an entry to edit?
Bundle extras = getIntent().getExtras();
if (extras != null) {
mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);
}
}
This has been working for me in my tests. If anyone spots problems,
please let me know. Is there any way to get Google's attention on
this, maybe have them update the tutorial? Or at least have them add a
warning that serious bugs remain, even in their final version?
--
You received this message because you are subscribed to the Google
Groups "Android Beginners" group.
NEW! Try asking and tagging your question on Stack Overflow at
http://stackoverflow.com/questions/tagged/android
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-beginners?hl=en