1

Confusing results... I have 5 progressBars in an activity working fine.

But after some time the UI almost grinds to a halt.

How can I be sure my 5 progressBar's handlers exit on completion after reaching the progressBars MAX?

Below is an example of one of the Progressbars in my activity.

public void doProgressBarA() {

    maskBar4 = (progBar) child2.findViewById(R.id.fragmentB_progressBar4);
    new Thread(new Runnable() {//Start long running op in background thread
        public void run() {
            final SharedPreferences nnn =       getSharedPreferences("com.blagmyname.app", MODE_PRIVATE);
              int spRateValue = nnn.getInt("current_name_number", 0);
            while (m4progressStatus < spRateValue) {
                m4progressStatus += 3;
                // Update the progress bar and display the current value in the text view
                mask4handler.post(new Runnable() {
                    public void run() {
                        maskBar4.setProgress(m4progressStatus);
                    }
                });
                try {   // Sleep for 20 ms to display the progress slowly
                    Thread.sleep(8);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }).start(); 
}
//////////////////////////////////////////////////////////////////////////// 
  • 2
    Probably updating the progress bar way too often. I think you should use asynctask for this anyways. http://stackoverflow.com/questions/9671546/asynctask-android-example There is an `onProgressUpdate()` method in it – WalterM Nov 29 '15 at 22:51
  • I am using it to animate 5 ProgressBars in sequence do you really think that would be the problem? –  Nov 29 '15 at 22:54
  • Thanks for the pointer. I used the following as it was self explanatory for a newbie like me. http://android-er.blogspot.co.uk/2014/04/run-multi-asynctask-as-same-time.html –  Nov 29 '15 at 23:37
  • Did my answer help? If so, please mark it best answer. If you have any questions, feel free to ask me – Ruchir Baronia Nov 30 '15 at 00:44

2 Answers2

1

Aysynctask is perfect for this scenario. But, in aysynctask, you will not be able to update the GUI from there. You will update the GUI after method doInBackground completes.

The reason I say aysynctask is perfect for this scenario is because of the onProgressUpdate() method. You can update your progress bar through that. To use aysynctask, just call the .execute() method on your object. Then, that will call the AysyncTask class. You will need to make this class, and put at least one of the AysyncTask methods in:

enter image description here

www.willcode4food.net

Notice the onProgressUpdate method in the diagram. From there, you can update your progress bar, which doesn't need to even be updated that often:

enter image description here

xsun.info

I highly suggest looking at the android docs and online for examples of aysynctask. It won't be difficult, just copy and paste your thread contents into another asyncTask class.

Look at this:

http://developer.android.com/reference/android/os/AsyncTask.html

user229044
  • 232,980
  • 40
  • 330
  • 338
Ruchir Baronia
  • 7,406
  • 5
  • 48
  • 83
0

I threw this example together, and commented to make it more obvious what's going on.

    progressBar = (ProgressBar)findViewById(R.id.progress_bar);

    new Thread(){
        //10 times a second. the lower this is the more often the progress bar updates.
        static final int UPDATE_DELAY = 1000 / 10;

        static final int WHAT_UPDATE_PROGRESS = 1;
        static final int WHAT_UPDATE_PROGRESS_STOP = -1;

        Handler handler = new Handler(Looper.getMainLooper(), new Handler.Callback() {
            @Override
            public boolean handleMessage (Message msg) {
                switch (msg.what){
                    case WHAT_UPDATE_PROGRESS: {
                        //do update on progress bar
                        progressBar.setProgress(progress);

                        //resend message back to same handler at a delay
                        handler.sendEmptyMessageDelayed(WHAT_UPDATE_PROGRESS, UPDATE_DELAY);
                    }   return true;
                    case WHAT_UPDATE_PROGRESS_STOP: {
                        //do update on progress bar for final time
                        progressBar.setProgress(progress);
                        //remove all messages from handler to do with updating
                        handler.removeMessages(WHAT_UPDATE_PROGRESS);
                        {
                            //do whatever you want here, on the main thread when finished.
                            Toast.makeText(getApplicationContext(), "Done", Toast.LENGTH_SHORT).show();
                        }
                    }   return true;
                }
                return false;
            }
        });

        //volatile to ensure it is the same across all threads.
        volatile int progress = 0;

        @Override
        public void run(){
            try {
                progressBar.setMax(1000);
                //send first message to start updating progressbar
                handler.sendEmptyMessage(WHAT_UPDATE_PROGRESS);

                //this is where your logic goes.
                for (int i = 0; i < progressBar.getMax(); i++) {
                    progress++;
                    try {
                        Thread.sleep(10);
                    } catch (Exception e) {
                        Thread.currentThread().interrupt();
                    }
                }
            } finally { 
                //if finished, or something fails - make sure to stop updating progress
                handler.sendEmptyMessage(WHAT_UPDATE_PROGRESS_STOP);
            }
        }
    }.start();
WalterM
  • 2,686
  • 1
  • 19
  • 26