Making a interval timer in Java android

47,129

I would always recommend using a Handler.

It's a little more work than the built in classes, but I find that it is vastly more efficient and you have more control over it.

The Handler is a class that will handle code execution over a specific Looper / Thread by default, the Thread it is created in, Otherwise you can specify where the Handler executes its code by passing in the Looper to the Handler constructor like - new Handler(Looper.getMainLooper());

The reason I would recommend the looper is because you have a higher flexibility of control, as it is a slightly lower down abstraction over the TimerTask methods.

Generally they are very useful for executing code across threads. E.g. useful for piping data across threads.

The two main uses are:

public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);

    final Handler h = new Handler();
    h.postDelayed(new Runnable()
    {
        private long time = 0;

        @Override
        public void run()
        {
            // do stuff then
            // can call h again after work!
            time += 1000;
            Log.d("TimerExample", "Going for... " + time);
            h.postDelayed(this, 1000);
        }
    }, 1000); // 1 second delay (takes millis)
}

Simple use!

Or you can use messages, which reduce object creation. If you are thinking about high speed updating UI etc - this will reduce pressure on the garbage collector.

class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        MyTimers timer = new MyTimers();
        timer.sendEmptyMessage(MyTimers.TIMER_1);
        timer.sendEmptyMessage(MyTimers.TIMER_2);

    }


    public static class MyTimers extends Handler
    {

        public static final int TIMER_1 = 0;
        public static final int TIMER_2 = 1;

        @Override
        public void handleMessage(Message msg)
        {
            switch (msg.what)
            {
                case TIMER_1:
                    // Do something etc.
                    Log.d("TimerExample", "Timer 1");
                    sendEmptyMessageDelayed(TIMER_1, 1000);
                    break;
                case TIMER_2:
                    // Do another time update etc..
                    Log.d("TimerExample", "Timer 2");
                    sendEmptyMessageDelayed(TIMER_2, 1000);
                    break;
                default:
                    removeMessages(TIMER_1);
                    removeMessages(TIMER_2);
                    break;
            }
        }
    }
}

Obviously this is not a full implementation but it should give you a head start.

Share:
47,129
Hans Fredrik
Author by

Hans Fredrik

Updated on February 25, 2020

Comments

  • Hans Fredrik
    Hans Fredrik about 4 years

    I have plans to create an interval app using timers. It should just be the most basic So I'll have to add some more when I've understood the basics. What I want to achieve is to select the number of minutes an interval should last, yet how many times this interval should go. Like a interval that last 1 minute and goes 8 times. The question is which timer is best to use? I have tried me on the Android Countdown Timer and it seems to work. But is there another one which is better?

  • Hans Fredrik
    Hans Fredrik over 11 years
    Thank's alot for feedback Chris! I am still a little confused unfortunately. Since Im still in the learning proccess it is some stuff that I need to get. So I looked at your example and also searched about Handler. And I diddn't completely get it, is handler a kind of a thread or is it handling threads ? I feel kind of dumb that I don't understand this hehe, but I felt it is better to ask than just get confused. And do you have a example that is complet? A very very small one. I tried the one above with handler, and it does execute the lines ine the //do stuff.Again Thank's alot for answers:)
  • Chris.Jenkins
    Chris.Jenkins over 11 years
    @user1779228 I have improved the answer with more code (I made a few mistakes, apologies). Handlers are a bit wierd to get you head around at first but they are VERY powerful tool to know/use. If you have ever used the Activity method of runOnUiThread(Runnable) that basically passes your Runnable object to a Handler which is assigned the UI thread to make so it runs there. But as mentioned above you can do timing functions with it, Which make it really useful.
  • Hans Fredrik
    Hans Fredrik over 11 years
    Thank's mate! I kind of understand it now:) So it did help alot. But still the app I want to make just to get more experience is not as easy as I thought hehe. So Im not quiet sure how to make it yet, But Im watching some tutorials and learning more so maybe i will come over a good solution. If you know some good way to get started I wouldn't say no to any help! :D But thank's for the help so far Chris! I will mark your answer as right answer!
  • Chris.Jenkins
    Chris.Jenkins over 11 years
    no problem, well if there complicated questions ask them here, otherwise just tweet me @chrisjenx. Just draw out some user flow and that will indirectly help you architect the app. :)
  • Raphael C
    Raphael C over 9 years
    I just would like to point out an important note on this method of implementing an interval with a recursive call. If the stuff you are doing is taking a certain amount of time, the intervall frequency will always be greater than the real time frequency. for exemple, you call the method after a second, then you do something (which can take maybe 50ms) and then you recall the method after 1sec. the actual frequency is not 1sec, it becomes 1050ms, and even more confusing can be random depending on the time the app took to execute the stuff you actually want to do.
  • Raphael C
    Raphael C over 9 years
    EDIT: if real time frequency is actually important for you, I would rather recommend using Timer class and scheduleAtFixedRate method.
  • vcapra1
    vcapra1 about 9 years
    @RaphaelC - the frequency actually decreases, as each interval is longer, so the method is called less often. The period increases, but the frequency is reduced. So 1000ms is the period, and therefore 1/sec is the frequency, so if the period is 1050ms, then the frequency is about .95/sec
  • Raphael C
    Raphael C about 9 years
    @VinnieCaprarola exactly. thanks for fixing my comment, but overall you got what I wanted to point out ;-)
  • Aviv Ben Shabat
    Aviv Ben Shabat about 6 years
    I guess that the Handler can just call post(Runnable r) with no delay for the first run. The delay can be inside the Runnable.
  • topher217
    topher217 almost 4 years
    @RaphaelC, looks like the Timer class is also not "real-time", but can get closer to the expected interval via some handling of the garbage handling and other time consuming tasks. > This class does not offer real-time guarantees: it schedules tasks using the Object.wait(long) method.
  • Raphael C
    Raphael C almost 4 years
    @topher217 nevertheless, as you said, it gives a closer behaviour to realtime than the recursive solution discussed above. furthermore, "real-time" is a very wide concept which many people will have a hard time agreeing upon especially when relativity is involved.