Search code examples
androidprogressdialog

Understanding how ProgressDialog works


I work with a Device with fix API 23 and because I thought it would be easy I wanted to use ProgressDialog since it is still available.

I tried to start a Thread which needs to do a lot of work and while he is doing this the user has to wait.

I got different issues while using the ProgressDialog:

1. Doesn't stop

public void buttun(View view) {

        ProgressDialog mProgressDialog = new ProgressDialog(this);
        mProgressDialog.show(this,"Title","Message",true);
        addCustomQueue.start();
        getCustomQueue.start();
        mProgressDialog.dismiss();
}

In this case with the button click the ProgressDialog shows up but .dismiss() doesn't work. (I know that the ProgessDialog should close immediately even when the Thread is not finished. I just wanted to know if .dismiss() works.)

2. To much work on MainThread

public void buttun(View view) {

        ProgressDialog mProgressDialog = new ProgressDialog(this);
        mProgressDialog.show(this,"Title","Message",true);
        addCustomQueue.start();
        getCustomQueue.start();

        try {
            addCustomQueue.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        mProgressDialog.dismiss();
    }

When I try to .join() one Thread which will surely end after 20 sec, the ProgressDialog shows up after about 30s and also .dismiss() doesn't work. But I got the information about the thread being finished.

The Style I want to use is the second one, but I need a proper way to do it. What is the right way to use this?


Solution

  • 1. Doesn't stop

    In fact, ProgressDialog.show(Context, String, String, boolean) is a static method, it creates a new ProgressDialog and return it after showing it.

    You should change your code like this.

    ProgressDialog mProgressDialog = ProgressDialog.show(this,"Title","Message",true);
    mProgressDialog.dismiss();
    

    2. Too much work on MainThread

    You should never block Android's MainThread, so join a thread on MainThread is not a good idea.

    Instead of joining a long-running thread on MainThread, you can use a Handler to post callbacks on MainThread.

    Your Activity:

    public class MainActivity extends AppCompatActivity {
    
        private ProgressDialog mProgressDialog;
        private AddCustomQueueThread addCustomQueue;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            addCustomQueue = new AddCustomQueueThread(this);
        }
    
        public void dismissProgressDialog() {
            if(mProgressDialog != null) {
                mProgressDialog.dismiss();
                mProgressDialog = null;
            }
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            if(mProgressDialog != null) {
                mProgressDialog.dismiss();
                mProgressDialog = null;
            }
        }
    
        public void button(View view) {
            addCustomQueue.start();
            mProgressDialog = ProgressDialog.show(this,"Title","Message",true);
        }
    }
    

    Your Thread:

    
        class AddCustomQueueThread extends Thread {
            final WeakReference<MainActivity> activity;
            final Handler handler;
            AddCustomQueueThread(MainActivity act) {
                activity = new WeakReference<>(act);
                handler = new Handler(Looper.getMainLooper());
            }
    
            @Override
            public void run() {
                super.run();
    
                //do your work.
    
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        MainActivity act = activity.get();
                        if(act != null) {
                            act.dismissProgressDialog();
                        }
                    }
                });
    
            }
        }
    

    Please note: we are storing reference to activity inside a WeakReference, this is needed to prevent leaking of your activity.