9

I have to wait some seconds in my Android App and I want to show a progress bar during this time, how can I do this?

I tried for example this code:

    public boolean WaitTask() {

        pDialog = ProgressDialog.show(context,null, "Lädt..",true);
        new Thread() {
        public void run() {
            try{
                // just doing some long operation
                sleep(2000);
             } catch (Exception e) {  }
             pDialog.dismiss();
             }
         }.start();
        return true;
   }

But the progressbar closes immediately without waiting the two seconds. Where is my problem?

The progressbar should look like the activity circle showing in this site from Android Developers.

UPDATE The AsyncTask

private class WaitTime extends AsyncTask<Void, Void, Void> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        mDialog.show();
    }
    protected void onPostExecute() {
        mDialog.dismiss();
    }

@Override
protected void onCancelled() {
    mDialog.dismiss();
    super.onCancelled();
}

    @Override
    protected Void doInBackground(Void... params) {
        long delayInMillis = 2000;
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                mDialog.dismiss();
            }
        }, delayInMillis);
        return null;
    }
}

I call it like this:

        mDialog = new ProgressDialog(CreateProject.this);
        mDialog = ProgressDialog.show(context,null, "Lädt..",true);

        WaitTime wait = new WaitTime();
        wait.execute();
Mokkapps
  • 2,028
  • 9
  • 42
  • 67
  • Maybe this post: http://stackoverflow.com/questions/2798443/android-progressdialog-doesnt-show will help – Mike Oct 02 '12 at 13:53
  • I tried the first two solutions without success. the progressbar disappears immediately... – Mokkapps Oct 02 '12 at 14:01
  • according to your asynctask update: timer's scheduled task run in background, so onPostExecute is called right after timer is scheduled in doInBackground, so dialog is dismissed immediately, see my answer for an example how to handle dialog with timer. – Berťák Oct 02 '12 at 16:11

2 Answers2

9

I reccomend you to use AsyncTask, then you can do something like this:

    AsyncTask<Void, Void, Void> updateTask = new AsyncTask<Void, Void, Void>(){
        ProgressDialog dialog = new ProgressDialog(MyActivity.this);
        @Override
        protected void onPreExecute() {
            // what to do before background task
            dialog.setTitle("Loading...");
            dialog.setMessage("Please wait.");
            dialog.setIndeterminate(true);
            dialog.setCancelable(false);
            dialog.show();
        }

        @Override
        protected Void doInBackground(Void... params) {
            // do your background operation here
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            // what to do when background task is completed
            dialog.dismiss();
        };

        @Override
        protected void onCancelled() {
            dialog.dismiss();
            super.onCancelled();
        }
    };
    updateTask.execute((Void[])null);

and if you want to wait for some specific time, maybe you would like to use Timer:

    final ProgressDialog dialog = new ProgressDialog(MyActivity.this);
    dialog.setTitle("Loading...");
    dialog.setMessage("Please wait.");
    dialog.setIndeterminate(true);
    dialog.setCancelable(false);
    dialog.show();

    long delayInMillis = 5000;
    Timer timer = new Timer();
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            dialog.dismiss();
        }
    }, delayInMillis);
Berťák
  • 7,143
  • 2
  • 29
  • 38
  • added my `AsyncTask` to my main post but it does not work. The ProgressBar dissapears without waiting the 2 seconds and the same LogCat error as in the post from Tal Kanel – Mokkapps Oct 02 '12 at 14:26
  • I could solve the error in LogCat but the progressbar still disappears immediately.... – Mokkapps Oct 02 '12 at 14:39
  • when you mixed my AcyncTask and Timer recommandations, try to remove dialog.dismiss() from onPostExecute and let it be dismissed by the timer. – Berťák Oct 02 '12 at 15:01
6

mistake: calling pDialog.dismiss(); should be done from the UI thread instead of called from your new thread.

so your code should change to:

pDialog = ProgressDialog.show(context,null, "Lädt..",true);
    new Thread() {
    public void run() {
        try{
            // just doing some long operation
            Thread.sleep(2000);
         } catch (Exception e) {  }
           // handle the exception somehow, or do nothing
         }

         // run code on the UI thread
         mYourActivityContext.runOnUiThread(new Runnable() {

            @Override
            public void run() {
                pDialog.dismiss();
            }
        });

     }.start();

generally - there are much better approaches performing background tasks (waiting and do nothing for two seconds is also background task) and performing something in the main UI thread when they finished. you can use AsyncTask class for example. it's better use this android built in mechanism, and not "primitive" thread creation, although it will work too - only if you will handle right your application and activity life-cycle. remember there is a chance that in the two seconds you are waiting - the user can navigate away from your application. in that case the dismiss(); method would be call on a destroyed context...

I suggest you read more in - http://developer.android.com/reference/android/os/AsyncTask.html

njzk2
  • 38,969
  • 7
  • 69
  • 107
Tal Kanel
  • 10,475
  • 10
  • 60
  • 98
  • You saw the {} after the catch() ? :-) – Heiko Rupp Oct 02 '12 at 14:05
  • If i try to run your code I get the following LogCat error `10-02 16:06:01.380: E/WindowManager(15154): Activity de.bertrandt.bertrandtknx.CreateProject has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@41aa7f10 that was originally added here 10-02 16:06:01.380: E/WindowManager(15154): android.view.WindowLeaked: Activity de.bertrandt.bertrandtknx.CreateProject has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@41aa7f10 that was originally added here` – Mokkapps Oct 02 '12 at 14:07
  • @Mr.Mojo: read the addition I've made in the bottom of my answer. that exactly what I'm warning you about.. – Tal Kanel Oct 02 '12 at 14:11
  • the sleep is called inside a Thread context, hence it is perfectly valid. the catch block is before the dismiss. The third point is valid, though – njzk2 Oct 02 '12 at 14:13
  • why not handler.postDelayed rather than an ugly sleep, btw ? – njzk2 Oct 02 '12 at 14:15
  • @njzk2: implementing the dismiss inside the "catch" is defiantly a mistake, assuming he wanted to dismiss the dialog when the two seconds will pass. that was the whole purpose of the thread.. – Tal Kanel Oct 02 '12 at 14:17
  • yes, but no, the dismiss is not inside the catch. Your code doesn't run, btw, you have a } misplaced – njzk2 Oct 02 '12 at 14:19
  • @njzk2: now I see that you right - I don't know why it looked like the dismiss is in the catch. it's my bad... and also the misplaced "}" – Tal Kanel Oct 02 '12 at 14:22
  • what if the background task runs for a long time? apparently you shouldnt use AsyncTask then? – filthy_wizard Jul 21 '15 at 09:52
  • I don't remember the context of the discussion, but of course that if your have long running task that runs in background - it would be smarter to use Service+AsyncTask , or IntentService class – Tal Kanel Jul 21 '15 at 09:59