5

I need stuff to be done every 200 milliseconds and I need it to be smooth and even. The task to do is medium-weight(in both cases, of the question 1 and 2). Searching for timers look like the best solution from the community is to use an handler, a runnable and postDelayed(), ( How to set timer in android? ).

Updated Questions:

-Which way is most precise and fast if I have to interact with the UI, postDelayed() or schedule()/scheduleAtFixedRate()?

-Which way is most precise and fast if I don't have to interact with the UI, postDelayed() or schedule()/scheduleAtFixedRate()?

-Both ways could be executed on the main process or on a separate one? how?

This way I have the mainclass local objects, but is it a new thread? Is it a good practice?

timer.schedule( new TimerTask() {           
        @Override
        public void run() {
                    textview.setText(str);
                    //other stuff            
                                     }
            }, 0, 200);

The next is another with schedule, the task is in a separate task, not the timer itself, I guess, and I can't interact with the UI directly, I guess...

timer.schedule( new aclass(), 0, 200);

Handler way(from Dave.B):

Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
    @Override
    public void run() {
        TextView.setText(str);
        // other stuff
        timerHandler.postDelayed(this, 500); }
};

@Override
public void onCreate(Bundle savedInstanceState) {
...
timerHandler.postDelayed(timerRunnable, 0);
}
Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Jackd
  • 131
  • 1
  • 2
  • 9
  • If you want stuff done on the main thread, use a handler with `postDelayed()`. Otherwise you are going to waste more time posting your event back to the main thread. – Alex MDC Sep 12 '14 at 02:15
  • The timer is fast so I suppose I need a new thread, but I have to interact with the UI – Jackd Sep 12 '14 at 15:54
  • In the end I think ill use the handler(3rd example), in a separate "helper" class. And this should put everything on another thred, correct? – Jackd Sep 22 '14 at 23:31
  • @Alex MDC.but I have to make another similar app that also interact with the UI. And you say that could be even slower if I run it on a separate class ? – Jackd Sep 22 '14 at 23:34

2 Answers2

7

Timer executes its tasks on a separate thread that is used only for serving tasks created by this particular timer. Handler runs its task on its Looper's thread which may or may no be a UI thread. Generally speaking there's no much difference between this two classes if you use Handler on a separate thread. But it's more common in Android to use Handler and HandlerThread.

If you need to interact with UI, you'd better use Handler on the main thread in order to avoid context switching. But in this case there may be some delays because performance of such timer will depend on the overall performance of the UI.

UPDATE: In the third example the Runnable is executed on the main thread. I assume that all the code in this example is located in an Activity subclass.

Handler, Timer and ScheduledExecutorService use the similar approach to scheduling tasks. I'm not sure you can get significant changes in precision or performance when switching from one implementation to another.

UPDATE: Finally, I would recommend you the following approach to choosing a timer:

  1. Use ScheduledExecutorService if you need a task to run on a separate thread or/and the task is too heavy for the main thread.
  2. Use Handler for running tasks on the main thread or if you need its message queue functionality.
  3. Do not use Timer, use ScheduledExecutorService instead.
Michael
  • 53,859
  • 22
  • 133
  • 139
  • Question1: I thought that both the task and the timer should be on a separate thread(or should i say on a separate process? the purpose is to not freeze the UI, like with any heavy job), also considering that the timer i need is fast. – Jackd Sep 12 '14 at 20:02
  • Question2: in the 3rd example that i added, are the task, and calling of the task on a separate thread/process ? – Jackd Sep 12 '14 at 20:05
  • @Jackd, `Handler` can be created with a given `Looper` and `Looper` represents a message loop. Every Android application has the main `Looper` that is bound to the main thread and can be accessed via `Looper.getMainLooper()` or `Context.getMainLooper()`. So you can run a periodic task on the main thread using `Handler`. It depends on your problem whether or not you should run it on the main thread. I think that in most cases you should run UI-bound periodic tasks on the main thread because such tasks do not a very precise timer. – Michael Sep 13 '14 at 19:03
  • An it doesn't make any sense to run such lightweight periodic tasks in a separate process so `Handler`, `Timer` and `Executors` are all inproc. If you really need it, you can run such a task in a separate process but in this case you have to understand why you want to do it. – Michael Sep 13 '14 at 19:07
  • @Jackd, In the third example the `Runnable` is executed on the main thread. I assume that all the code in this example is located in an `Activity` subclass. – Michael Sep 13 '14 at 19:09
  • Thanks Michael, I don't understand when you say " most cases you should run UI-bound periodic tasks on the main thread because such tasks do not a very precise timer " , I need precision. And the task to do is "medium-weight", and now I'd like to know in both cases, if I have and if I have not to interact with the UI. I'd like to give you the accepted question, but im still confused... – Jackd Sep 14 '14 at 21:21
  • @Jackd, when you say you need precision, what exactly do you mean? Should it have 10 ms accuracy or 100 ns? If 10 ms accuracy is acceptable, you can use `Handler` on the main thread. And if you need 100 ns accuracy, none of user space timers will help you. If your task is quite heavy, you should definitely run it on a separate thread. I would recommend you to start off with `Handler` on the main tread and if it doesn't work well, try all available timers and compare their performance. – Michael Sep 15 '14 at 07:44
  • @Jackd, I've just updated the answer. Maybe this new information will be useful for you. – Michael Sep 19 '14 at 13:20
1

I will rather use ScheduledThreadPoolExecutor because timer runs its task sequentially so if there are more than one tasks at a time, remaining tasks will get delayed. While ScheduledThreadPoolExecutor have pool of threads & it lets multiple tasks run in parallel, so no delay will be there.

Handler postdelayed method is for posting your runnable to the main UI thread in Android,You need it for doing all UI related stuff. Don't confuse timer with Handler postdelayed

Edit 1: For UI related stuff you can use handler postdelayed. e.g.

handler.postDelayed(new Runnable() {
        public void run() {
          textview.setText(str);
          //other UI related stuff      
        }
    }, 200);
Akhil
  • 6,667
  • 4
  • 31
  • 61
  • 1
    I think you wrong, handler instance can be created for any thread (even not ui threads), there is method like `runOnUiThread` which is really only for ui – user924 Sep 01 '17 at 09:26