Question

I have had this "issue" for sometime on my app and it always bothered me that I didn't understand it's behavior, but never cared about asking why, until now.

I have a ListView (implemented through a ListActivity) with a custom layout for each list item. With that I have a custom CursorAdapter to properly fill all the list item elements (overriding newView and bindView, the ViewHolder pattern is already guaranteed when doing it like this, refer to: https://codereview.stackexchange.com/q/1057 if needed).

This is the main Activity and there are 2 actions that can update the content of the ListView, create a new item or edit a current one. For both, the same activity is used (which adapts itself to the type of action), something like this:

startActivityForResult(intent, ACTIVITY_NOTE_EDITOR_CREATE);
startActivityForResult(intent, ACTIVITY_NOTE_EDITOR_EDIT);

What actually distinguishes the action type is the intent contents, the requestCode is ignored in the sub activity.

Now, the documentation has this to say about the method above:

When this activity exits, your onActivityResult() method will be called with the given requestCode.

But I'm not using onActivityResult. Actually, I'm not doing anything when the sub activity exists (either in create or edit mode). And the behavior I've noticed so far is this:

  • Create: Almost all the time I return to the main activity, the ListView is automatically updated with the new item. However, sometimes, rarely though, the ListView is not populated with the new item. I need to destroy the main activity (exiting the app for instance) and recreate it and then the new item will be there.
  • Edit: I never noticed similar behavior as just described for the create action. So far, the ListView was always automatically updated with the new content changes.

My question is, what's happening behind the scenes that makes my ListView to automatically update it's contents when I never call cursor.requery() nor manually notify of any changes to the content? And why the hell doesn't it work all the time?

Should I maybe force a cursor.requery() myself on onActivityResult?

public class MainActivity extends ListActivity {

    private static final int ACTIVITY_NOTE_EDITOR_CREATE = 0;

    private NotificationHelper mNotificationHelper;
    private AgendaNotesAdapter mAgendaAdapter;
    private Cursor mAllNotesCursor;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        mNotificationHelper = Program.getNotificationHelper();

        mAgendaAdapter = new AgendaNotesAdapter(this);
        mAgendaAdapter.open();

        initializeNotesListActivity();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        Intent intent;

        switch(item.getItemId()) {
            case R.id.actionbar_item_new_note:
                intent = NoteEditorMainActivity.createIntent(this);
                startActivityForResult(intent, ACTIVITY_NOTE_EDITOR_CREATE);
                return true;
        }

        return false;
    }

    private void initializeNotesListActivity() {
        mAllNotesCursor = mAgendaAdapter.fetchAllNotes();
        startManagingCursor(mAllNotesCursor);

        NotesListAdapter notesAdapter = new NotesListAdapter(this, mAllNotesCursor,
                mNotificationHelper, mAgendaAdapter);

        setListAdapter(notesAdapter);
    }

}

P.S: I know about CursorLoader and it's something in the roadmap, but I don't have time to deal with such code rewrites for the time being. Just thought I'd let you know. For now, I just need to know what is happening with my current code.

No correct solution

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top