1

what I want to achieve is Upon click, app shows toasts message "TEXT1", and keeps showing TEXT1 until finish other function call 20 times at a random interval/delay. After calling function,shows toast message "TEXT2". My problem: TEXT1 does not show until app finishes function call. and TEXT1 keeps up for the time it takes to execute 20 times function call,then TEXT2 shows up.My code:

public void onClick(View v) {
    switch (v.getId()) {
        case R.id.example:
                Toast.makeText(getBaseContext(),"Please wait until finish",Toast.LENGTH_SHORT).show();
                int i = 0;
                while (i <= 19 ){

                    int delay = new Random().nextInt(5000);
                    try {
                            Thread.sleep(delay);
                        } catch(InterruptedException ex) {
                            Thread.currentThread().interrupt();
                        }
                    //some function here
                    i++;
                }
                Toast.makeText(getBaseContext(),"Finished",Toast.LENGTH_SHORT).show();
                break;
        }
    }
}
SOFe
  • 7,867
  • 4
  • 33
  • 61
tikael
  • 439
  • 4
  • 15

1 Answers1

1

Never block the UI thread!

All user interface operations are handled in the UI thread. If you block the UI thread with a Thread.sleep call, an ANR (Application Not Responding) will occur. Moreover, Thread.sleep is never the right way to create timers, unless you are writing the core heartbeat of a worker thread.

Instead, you should use Handler.postDelayed:

public void onClick(View v) {
    final Handler handler = new Handler();
    final Random random = new Random();

    Runnable runnable = new Runnable() {
        private int count = 0;

        @Override
        public void run() {
            count++;
            if(count > 20) { // 20 times passed
                Toast.makeText(getBaseContext(), "Finished", LENGTH_SHORT).show();
                return;
            }

            Toast.makeText(getBaseContext(), "Please wait until finish", LENGTH_SHORT).show();
            handler.postDelayed(this, random.nextInt(5000));
        }
    };
    runnable.run();
}

Edit: the OP wanted to use something like this. https://gist.github.com/SOF3/07c3c110aa214fcdd752e95573b7076f

See also:

Graham
  • 7,431
  • 18
  • 59
  • 84
SOFe
  • 7,867
  • 4
  • 33
  • 61
  • this method calls my function at a FIXED interval,which is not I want. – tikael Sep 18 '16 at 05:42
  • Then just change the 1000 to your random number. But didn't you say that you want the toast message to show up consistently? – SOFe Sep 18 '16 at 05:43
  • yes, I did.so basically my code should be something like: `final Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { } }, Myrandomnumber);` ? – tikael Sep 18 '16 at 05:48
  • Delay it with `random.nextInt()`. Make the `Random` object `final`. Create a class field that stores how many times this runnable has been called. Editing in a minute to show you how. – SOFe Sep 18 '16 at 05:50
  • @tikael Edited. – SOFe Sep 18 '16 at 05:55
  • I tested, the toast msg does not show...though the UI keeps updating. – tikael Sep 18 '16 at 06:02
  • Does it show the first time? Did you add the last line `runnable.run()`? It is unreasonable that it doesn't show any toasts (unless you have problems your side), because the runnable must at least show a toast either way, postDelayed or not. – SOFe Sep 18 '16 at 06:03
  • it does not and I did add the runnable.run() – tikael Sep 18 '16 at 06:05
  • @tikael Add a logcat message in the `run` method inside the Runnable. If your code is run, that logcat message must show. If the logcat message shows but the toast doesn't show, your toast has a problem. – SOFe Sep 18 '16 at 06:09
  • I added `Log.i(TAG,"yes"); ` right under the "please wait..."and I can see TAG:yes in the logcat--info window..still no toast message...so weird. – tikael Sep 18 '16 at 06:14
  • Try changing your context? Maybe you are using the wrong context. – SOFe Sep 18 '16 at 06:16
  • one more thing, the whole function calls toast for each loop, is there a way to show the "please wait.." constantly? maybe I should customize the `Toast.LENGTH`? – tikael Sep 18 '16 at 06:21
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/123623/discussion-between-pemapmodder-and-tikael). – SOFe Sep 18 '16 at 06:21