Jim Clay
Jim Clay

Reputation: 1003

Progress dialog during tab switch

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:

  1. Activity B onCreate - creates ProgressDialog and puts long tasks in a background Thread.
  2. Activity B onStart
  3. Activity B onResume
  4. Activity B appears on the screen

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

Answers (3)

Jim Clay
Jim Clay

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:

  1. onCreate
  2. Create object
  3. Create progress dialog
  4. Create background thread, have it do long initialization of object.
  5. onStart
  6. onResume (with no check/sleep loop).

Upvotes: 0

Sam
Sam

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

trutheality
trutheality

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

Related Questions