Android ListView not updating after long running process
I have a fairly complex problem. I have read some similar posts to my problem but in a slightly different situation.
I have an Activity with a List View. The Activity creates a thread with a long running process. After the process ends, it calls the handler to update the listview and play a sound. It works fine if I'm in the same Activity, but when I click on HOME button while the process is running, then press on the shortcut or application icon to launch the Activity, then when the process ends, I hear the sound but the list view is not updated. Any ideas why this is happening? Some people and me as well are getting the same issues with orientation change.
// thread created to send the reply.
Thread replyThread = new Thread() {
public void run() {
**Http POST here to upload an image which takes a while.
//Once done, send a msg to handler to play a sound and update listview
Message msg = replyHandler.sendEmptyMessage(0);
}
}
Handler:
final Handler replyHandler = new Handler() {
public void handleMessage(Message msg) {
fillData();
**Code to play sound.
}
}
fillData() method
// refresh the listview.
private void fillData() {
// Get all of the rows from the database and create the item list
**I actually have an activity before this one but to simplify the problem I said I have 1 Activity. Bundle is from previous Activity.
String conver开发者_StackOverflow中文版sationId = "";
Bundle extras = getIntent().getExtras();
if (extras != null) {
conversationId = extras
.getString(TestDbAdapter.KEY_CONVERSATION_ID);
}
if (mDbHelper != null) {
Cursor notesCursor = mDbHelper
.fetchAllMessagesByConversationId(conversationId);
startManagingCursor(notesCursor);
String[] from = new String[] { TestDbAdapter.KEY_BODY,
TestDbAdapter.KEY_TIMESTAMP };
int[] to = new int[] { R.id.text1, R.id.text2 };
// Now create a simple cursor adapter and set it to display
MessagesCursorAdapter notes = new MessagesCursorAdapter(this,
R.layout.messages_row, notesCursor, from, to, mDbHelper);
setListAdapter(notes);
}
}
I know some people are gonna say "Use notifyDataSetChanged instead", done that. The code above works in the same manner as notifyDataSetChanged but maybe not in a very elegant way but in my case it works, but it doesn't help with the problem I'm having using notifyDataSetChanged.
When the home button is pressed and activity restarted a "new" activity is created.
Your callback from the long running process will be sent to the old activity, not the new activity.
A similar thing happens with orientation changes, each orientation change creates a new activity (that will not receive the callback).
There are a couple of methods I am aware of to deal with this:
- Store the state & results of the long running process in local storage (db, xml, contentprovider etc) and query for state & results when the activity starts. The Google IO REST talk talks about the problem and a pattern you can implement to solve it. (Note: fairly large amount of work to implement this pattern fully)
- Route the callbacks through your Application class and register your activities when they start with the Application so it knows which one to send callbacks to. Droid-fu contains some utilities that can help implement this
精彩评论