简体   繁体   中英

Java Timer equivalent in Android

I recently began working with Java and am exploring Android development. I was trying to port over one of the Java programs I made, but I am having some difficulty with getting the java Timer to function the same way in Android. I read through a number of posts and they, for the most part, indicated that it would be better to use the Handler class in android as opposed to Timer.

This was my timer in Java:

playTimer = new Timer(1000/model.getFPS(), new ActionListener() {
    public void actionPerformed(ActionEvent evt) {
        // do something
        ...
        if( finished everything ) playTimer.stop();
    }
});

And once a certain button was clicked, I would simply run "playTimer.start()" to start it.

As you can see, I had it set up so that the user could set the FPS they wanted (by simply setting the first parameter of the Timer class to 1000/model.getFPS()).

Now I've tried to do something similar in Android using handlers, but I am having some difficulty. It appears that the Handler ticks are not firing at the proper intervals. It seems that they are quite slow compared to what I need it to be. This is what I did in android so far:

public void startTimer() {
    playHandler = new Handler();
    startTime = System.currentTimeMillis();
    playHandler.removeCallbacks(updateTimeTask);
    playHandler.postDelayed(updateTimeTask, 0);
}

private Runnable updateTimeTask = new Runnable() {
    public void run() { 
        // do something
        ...

        if( finished everything ) playHander.cancel();
        else {
            playHandler.postDelayed(updateTimeTask, 1000/model.getFPS());
        }
    }
};

Excuse the semi-pseudocode. Can anyone shed any light? Thanks guys.

You can use a timer as below. The timer runs every second incrementing the counter. Displs the counter value in textview.

Timer runs on a different thread. SO you should set the text on the UI Thread.

The counter runs from 0 to 99. After 99 the timer is cancelled. Also cancel the timer when not required like in onPause() .

public class MainActivity extends Activity {
TextView _tv,tv2;
Timer _t;
int _count=0;


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    _tv = (TextView) findViewById( R.id.textView1 );
    _t = new Timer();
    _tv.setText(R.string.app_name);
    _t.scheduleAtFixedRate( new TimerTask() {
            @Override
            public void run() {
                _count++;

                runOnUiThread(new Runnable() //run on ui thread
                 {
                  public void run() 
                  { 

                      _tv.setText(""+_count);
                      if(_count==99)
                      {
                          _t.cancel();
                      }
                 }
                 });
            }
        }, 1000, 1000 ); //change this value of 1000 to whatever you need.


}
@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();

    _t.cancel();
}  
}

Take a look at Android Timer It already has everything you need i guess. From ticking every 1 second to finish handly and so on.
Here is an example how to setup an TimerTask: setup Not sure if you need such but i just remembered that i made this.

If you decide not to use Timer (for whatever reason) you can just write a separate Thread that sleeps for x milliseconds and then wakes up and calls whatever Runnable you want it to call. That's going to be pretty precise. I have it working at the 10 millisecond level and it works quite nicely.

Just remember that it HAS to call a Runnable because a separate Thread can't have direct effect on anything on the main display thread.

public boolean keepPlayingAnimation = true
Handler h = new Handler()
Runnable updateDisplay = new Runnable(){
  public void run(){

        //do something in my display;
  }
}

new Thread(){
  public void run(){
     while(keepPlayingAnimation){
       try{
          sleep(10);
       }catch(Exception e){

       }
      h.post(updateDisplay);
     }
   }
}.start();

Just don't forget to set keepPlayingAnimation to false when you're done with this cause otherwise it will sit there running in the background for ever (or just about).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM