Here's scenario:
- I have 2 activities and one service
- First activity is a landing view/search page. Second activity displays search results
- Search is always executed against internal SQLite db
- Periodically (say daily) db needs to be updated from the remote source which is a long process
- If user performs the search during the update I want to wait until the update is over while displaying "Please wait" progress alert. I don't want to query and display search results until refresh is fully done.
- The db update is triggered by AlarmManager and execu开发者_开发知识库ted by service which puts "UPDATING" status into db while update is in progress
- I can easily query the status but how do I wait and periodically re-query the database? I'm using AsyncTask to process search results and my knee-jerk reaction was to put a loop with wait() into
AsyncTask#doInBackground
method but that's dangerous and simply doesn't work since I'm not controlling the UI thread so I end up withIllegalMonitorStateException
.
What would be a "right" way to properly wait (may be even with status update) in this case?
P.S. I placed the "wait" code into a Runnable and executing it even before I get to my AsyncTask. It works e.g. Thread.sleep(2000)
still I'm not sure that's the way to do it safely. Does anyone have any experience with FutureTask
?
If user performs the search during the update I want to wait until the update is over while displaying "Please wait" progress alert. I don't want to query and display search results until refresh is fully done.
That's your call, but bear in mind you are creating your own problem. Personally, I'd dump this requirement. The user should not be inconvenienced just because an alarm went off.
For example, you could disable the alarm and re-enable it when the activity goes away.
Or, have the update be performed in such a way that it is atomic (e.g., do the update on a copy of the table, then sync the tables in a transaction), so that the activity can still safely access the database while the update is occurring.
What would be a "right" way to properly wait (may be even with status update) in this case?
Have the service tell the activity when the update is done, via some sort of callback, or perhaps a broadcast Intent. Keep the progress indicator alive until this occurs. This still introduces some timing challenges, which is why I'd just dump the requirement.
Thanks to Mark (as always) for useful insights. Here, I'm going to outline how (in my mind) the above scenario should be done:
- Instead of poking the database simply bind to the service and start waiting
- If you can't bind to the service then it's not running so there's no need to monkey with it - just query the db and do what you need
- When service is up, start waiting and process any feedback that service sends back. These can be interim updates and then final indicator that service is done
精彩评论