11

I want to cause my program to pause for a certain number of milliseconds, how exactly would I do this?

I have found different ways such as Thread.sleep( time ), but I don't think that is what I need. I just want to have my code pause at a certain line for x milliseconds. Any ideas would be greatly appreciated.

This is the original code in C...

extern void delay(UInt32 wait){
    UInt32 ticks;
    UInt32  pause;

    ticks = TimGetTicks();
    //use = ticks + (wait/4);
    pause = ticks + (wait);
    while(ticks < pause)
        ticks = TimGetTicks();
}

wait is an amount of milliseconds

JuiCe
  • 4,132
  • 16
  • 68
  • 119
  • 2
    You haven't given enough information. Explain what your code does and why it needs to wait/pause. – Squonk Jul 18 '12 at 19:34
  • 1
    Trying to pause the main thread of your application would likely trigger an ANR. If you tell us what is you're trying to do there maybe a better solution than blocking the thread. – TJ Thind Jul 18 '12 at 19:39
  • Haha, I don't even really know why. I am converting a Palm Pilot program to Android, and it has a 'delay' function, I'll edit my original post and show you the C code. – JuiCe Jul 18 '12 at 19:41
  • 1
    @JuiCe : But what is the point of that `delay` procedure? Where is it used in the rest of the code and for what purpose? – Squonk Jul 18 '12 at 19:45
  • I really don't know, I'm going to close the question. I need to figure out more about whats going on before I ask it. From what I can tell it literally just makes the program wait, there are no calls to other threads before hand. – JuiCe Jul 18 '12 at 19:45

8 Answers8

18

You really should not sleep the UI thread like this, you are likely to have your application force close with ActivityNotResponding exception if you do this.

If you want to delay some code from running for a certain amount of time use a Runnable and a Handler like this:

Runnable r = new Runnable() {
    @Override
    public void run(){
        doSomething(); //<-- put your code in here.
    }
};

Handler h = new Handler();
h.postDelayed(r, 1000); // <-- the "1000" is the delay time in miliseconds. 

This way your code still gets delayed, but you are not "freezing" the UI thread which would result in poor performance at best, and ANR force close at worst.

FoamyGuy
  • 46,603
  • 18
  • 125
  • 156
  • So you reject the edit suggestion and you do not even bother add a semicolon on last line of your code, which was a main reason for edit suggestion. Okay then. – FanaticD Oct 04 '15 at 12:01
  • @FanaticD fair enough buddy... ease up some. I didn't notice the semi-colon. all I saw was a couple things made italic. – FoamyGuy Oct 04 '15 at 12:25
  • Alright, my apologies then, I was too quick to reply without time to chill out. Thank you. :-) – FanaticD Oct 04 '15 at 12:28
  • 1
    What if you want to make the runnable repeat multiple times? – Elijah Mock Jan 13 '20 at 04:09
9

OK, first of all, never implement a delay with a busy loop as you're doing. I can see where that comes from -- I'm guessing that the palm pilot was a single-process device with no built-in sleep() function, but on a multi-process device, a busy loop like that just brings the entire processor to its knees. It kills your battery, prevents normal system tasks from running properly, slows down other programs or stops them completely, makes the device unresponsive, and can even cause it to get hot in your hands.

The call you're looking for is Thread.sleep(). You'll need to set up to catch any interrupt exceptions that occur while you're sleeping.

Second, with event-based user interfaces such as Android (or pretty much any modern GUI system), you never want to sleep in the UI thread. That will also freeze up the entire device and result in an ANR (Activity Not Responding) crash, as other posters have mentioned. Most importantly, those little freezes totally ruin the user experience.

(Exception: if you're sleeping for short enough intervals that the user probably won't notice, you can get away with it. 1/4 second is probably ok, although it can make the application janky depending on the situation.)

Unfortunately, there's no clean and elegant way to do what you want if what you're doing is porting a loop-based application to an event-based system.

That said, the proper procedure is to create a handler in your UI thread and send delayed messages to it. The delayed messages will "wake up" your application and trigger it to perform whatever it was going to do after the delay.

Something like this:

View gameBoard;     // the view containing the main part of the game
int gameState = 0;  // starting
Handler myHandler;

public void onCreate(Bundle oldState) {
  super.onCreate(oldState);
  ...
  gameBoard = findViewById(R.layout.gameboard);
  myHandler = new Handler();
  ...
}

public void onResume() {
  super.onResume();
  displayStartingScreen();
  myHandler.postDelayed(new Runnable() { 
    gotoState1(); 
  }, 250);
}

private void gotoState1() {
  // It's now 1/4 second since onResume() was called
  displayNextScreen();
  myHandler.postDelayed(new Runnable() { 
    gotoState2();
  }, 250);
}
...
clemens
  • 16,716
  • 11
  • 50
  • 65
Edward Falk
  • 9,991
  • 11
  • 77
  • 112
  • By the way, I haven't tested any of that code, I just typed it in. Making it actually compile is left as an exercise for the reader. – Edward Falk Jul 18 '12 at 23:18
  • 1
    I appreciate it. I talked to the guy who wrote the palm code and it turns out the delay() function he wrote was only for testing purposes, so I won't be needing one. Thanks a lot for your time though, taught me some things which never hurts. – JuiCe Jul 19 '12 at 12:48
3

Do something like the following. Here is a link to the reference, this might be helpful.

final MyActivity myActivity = this;   

    thread=  new Thread(){
        @Override
        public void run(){
            try {
                synchronized(this){
                    wait(3000);
                }
            }
            catch(InterruptedException ex){                    
            }

            // TODO              
        }
    };

    thread.start();   
Community
  • 1
  • 1
prolink007
  • 33,872
  • 24
  • 117
  • 185
3

You can use the Handler class and the postDelayed() method to do that:

Handler h =new Handler() ;
h.postDelayed(new Runnable() {
    public void run() {
                 //put your code here
              }

            }, 2000);
}

2000 ms is the delayed time before execute the code inside the function

Gulshan Jangid
  • 463
  • 4
  • 7
1

Not sure why you want the program to pause. In case you wish to do some task in the background and use the results, look at AsyncTask. I had a similar question awhile back.

Community
  • 1
  • 1
Primal Pappachan
  • 25,857
  • 22
  • 67
  • 84
1

The SystemClock.sleep(millis) is a utility function very similar to Thread.sleep(millis), but it ignores InterruptedException.

Ken
  • 19
  • 1
0

I think Thread.sleep(....) probably is what you want you just may not be doing it correctly. What exactly are you trying to pause? Hopefully not the UI thread? Im guessing you have some background thread performing some tasks at some kind of interval? If so then Thread.sleep will put that particular thread to sleep for a certain time, it will not however pause all threads.

Jon Taylor
  • 7,865
  • 5
  • 30
  • 55
0
try {
    Thread.sleep(2000); //1000 milliseconds is one second.
}
catch (InterruptedException e) 
{
    e.printStackTrace();
}
Pang
  • 9,564
  • 146
  • 81
  • 122
rmoore
  • 9
  • 2