Reputation: 1003
When the user switches from tab A to tab B it takes a long time (6 seconds), so I put in a progress dialog to let the user know that the app is working on it. The timeline is as follows:
This all works great with one "minor" snafu- the app intermittently crashes because the onResume function references something that is created by the background Thread. It is, in other words, a classic race condition.
To fix the race condition I did a "join" on the thread right before the reference in onResume, but that makes the progress dialog not show up until the background thread is done (i.e. it shows up for a split second and then goes away) and the app acts like it is hung while the background thread is working. Apparently the progress dialog cannot show up until onResume completes.
My question is this: how can I get the ProgressDialog to show up without crashing the program? Or do I need to either get the offending reference out of onResume or live with the app acting hung?
Upvotes: 1
Views: 441
Reputation: 1003
I ended up using a kludgey solution wherein the onResume function waits for the intermediate result that it needs, but not for the entire background thread to finish. This is ugly, I know, but it appears to work.
The better long term solution, I believe, is to separate the creation of the needed object from the long initialization steps that it does when it is created. The timeline would then be:
Upvotes: 0
Reputation: 2579
Are you using Threading as provided by the Java platform or are you using the Android convenience classes?
I am referring to AsyncTask
. More than likely you are running in to issues with your Runnables posting at inconvenient times. The AsyncTask
class packages up these features nicely. Subclass AsyncTask
, specifying the types for your params, progress, and result. Then hide your dialog in the onPostExecute
method, while you perform background work in the doInBackground
method.
Sample code:
AsyncTask<Void, Void, Void> parseTask = new AsyncTask<Void, Void, Void>() {
@Override
protected void onPostExecute(Void result) {
// Dismiss the progress dialog
dismissDialog(PROGRESS_DIALOG);
}
@Override
protected Void doInBackground(Void... params) {
// Do background work
return null;
}
};
// Start the background thread
parseTask.execute();
Taken from a live code base. Also don't feel too bad, concurrent programming is easily one of the more difficult systems to program. It is promising that you were able to recognize and identify the race condition.
Upvotes: -1
Reputation: 23465
A dirty solution would be to have one ProgressDialog for steps 1 and 2, and then create a second identical-looking one for steps 3 and 4.
Upvotes: -1