Which thread does Runnable run on? - java

I want to update UI every 100ms. After searching in StackOverflow, I found a solution using Runnable and Handler like this
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
//update UI here
handler.postDelayed(this, 100);
}
};
runnable.run();
It works! But I have some questions:
Which thread does this Runnable run on? MainThread or another thread? Here is the docs about postDelay
Handler is attached MainThread, so is Runnable running on MainThread?
If Runnable is running on MainThread, why needs Handler? According to my knowledge, Handler is used to send messages between two threads

Which thread does this Runnable run on?
Runnable runnable = new Runnable() {
#Override
public void run() {
//update UI here
handler.postDelayed(this, 100);
}
};
runnable.run()
This Runnable runs on the current thread, i.e. the thread that invokes this code. It doesn't magically create, or constitute, another thread. Runnable.run() is only a method call.
The subsequent executions of this thread, by the Handler, in whatever thread the Handler runs in, do essentially nothing except reschedule themselves. It's hard to believe this is a solution to anything.

In your example, the Runnable runs on the UI Thread.
If you want your Handler and all its Runnable to run in a different Thread, you'll have to assign it a a new HandlerThread's Looper.
final HandlerThread handlerThread = new HandlerThread(MY_THREAD_ID);
handlerThread.start();
final Handler handler = new Handler(handlerThread.getLooper());
You can then pass the Runnable instance via postDelayed(Runnable, long).
Runnable r = new Runnable() {
#Override public void run() {
handler.postDelayed(this, 2000);
}
};
handler.postDelayed(r, 0);

Handler is attached MainThread, so is Runnable running on MainThread?
From Handler documentation:
Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.
If you want to run your Runnable on different Thread, you can use HandlerThread .
Related post:
Why use HandlerThread in Android
If Runnable is running on MainThread, why needs Handler? According to my knowledge, Handler is used to send messages between two threads
There are two main uses for a Handler:
To schedule messages and runnables to be executed as some point in the future
To enqueue an action to be performed on a different thread than your own.
If you are using only MainThread,Handler is useful to send message at some point of time in future. If you are using different Threads, Handler is useful to communicate between the threads.

Related

after onPause() method stop "active" handler

calling the method handler.removeMessagesAndCallbacks(null) stops all handlers which are not executed yet (post delayed). but i need a method i can't find which interrupts the handler already running.
a thread can be interrupted while being executed. can a handler also be interrupted like a thread?
here an example:
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
> ...
}, 0);
handler.postDelayed(new Runnable() {
> ...
}, 1000);
#Override
protected void onPause() {
> super.onPause();
> handler.removeMessagesAndCallbacks(null);
}
the post delayed handler of 1000 is canceled, but the other handler is still being executed when calling onPause(), when already running.
Can i cancel a handler already being executed? Is there an easier opportunity than Override the Runnable or Handler class? If not, can somebody tell me how to Override, only for the case to cancel the runnable in the handler?
In my case the handlers are executing post delayed animations. I cannot cancel every single animation programatically. the runnable (handler) should be canceled including the animations should be canceled too. Thank you!
I think a good practice for what you want is using kotlin coroutines.
by using coroutines you can define some jobs that can be executed in the main thread or background threads. but the good point about them is that you can cancel them at any time you want by using job.cancel().
and if you want to do this with runnable and java maybe this question can help you:
Android: How do I stop Runnable?

Each Android thread is associated with Looper(Message Queue)?

I am trying to understand threads,handlers,loopers. I have watched the video where guy said following Each Android thread is associated with Looper(Message Queue). So that means that when I am creating Thread class instance it is implictly creates it own looper which is connected to this thread ? Or this is wrong ? Handler is connected to the thread where it was created, if there is no looper in each thread where handler will post messages ?
And another question is about HandlerThread . What is the purpose and what are pros and cons of using this class.
I hope for your help.Thanks everyone in advance.
EDIT
I wonder if Looper is associated with thread after just calling for example
Thread myThread = new Thread();
Or you should specify explictly lopper for thread calling Looper.prepare(); in your thread in turn implictly creating new instance of looper associated with the thread where method has been called. As I can see in sources of Looper class it calls ThreadLocal.get in prepare where is it gets current thread. So conclusion is that there is no looper associated with simple thread by default ? Am I right ?
And I have also noticed that all constructors of the Handler call Handler(Callback callback, boolean async). Looper.myLooper(); method is called.
So as I have understood it means following.
Thread myThread = new Thread(new Runnable() {
public void run() {
//some stuff here
}
});
myThread.start();
No Looper here is associated with thread.
Next example.
Thread myThread = new Thread(new Runnable() {
public void run() {
Handler myHandler = new Handler();
}
});
myThread.start();
Here Handler will be associated with looper implictly while creating new instance of Handler.
Next example.
Thread myThread = new Thread(new Runnable() {
public void run() {
Looper.prepare();
}
});
myThread.start();
In this example loooper will be created to explictly by calling prepare method.
I am right ? Please comment.
EDIT 2
The second example will cause
java.lang.RuntimeException: Can't create handler inside thread that
has not called Looper.prepare() such exception so conclusion is that
only thread that has called Looper.prepare()
; will have it's own Looper otherwise it will cause exception while creating handler inside such thread.
A thread becomes associated with a message queue by calling Looper.prepare(). Any Handler subsequently created in that thread will be associated with the same message queue. The thread begins processing its message queue by calling Looper.loop(). A looper thread typically won't do anything except process its own message queue.
From my understanding, Looper and Handler are just helper classes for easily handle generate and handle message in threads. But thread can do anything besides handling message.

What is the best way to wait until a runnable on the main thread completes in Android?

I need to collect a username and password from a user inside WebViewClient#shouldInterceptRequest, so I must block the WebView IO thread until the user supplies a username and password on the main thread. What is the best way to wait until my runnable completes?
My current favorite way is (exceptions and timeouts omitted for brevity):
final CountDownLatch countDownLatch = new CountDownLatch(1);
new Handler(Looper.getMainLooper()).post(new Runnable() {
public void run() {
callSomethingWithAsyncCallback(new Runnable() {
public void run() {
countDownLatch.countDown();
}
});
}
});
countDownLatch.await();
Something that uses ExecutorServices seems better since I can simply use Future#get to block. However, there is no ExecutorService that runs on the main thread, and using one from Executors just to bounce it to the main thread seems wasteful. Thoughts?
Please use AsyncTask rather than using runnable.
The AsyncTask executes everything in doInBackground() inside of another thread, which does not have access to the GUI where your views are.
preExecute() and postExecute() offer you access to GUI before and after the heavy lifting occurs in this new thread, you can even pass the result of the long operation to postExecute() to then show any results of processing.

Stopping a Timer Task from within a Runnable thread when shutdown

I have a TimerTask that gets started as the first thing in my run() method of my Runnable class. I want to make sure that it gets stopped when the runnable is shutdown.
The runnable is started via an ExecutorService. I don't see a way to get a hook back to the runnable from the ExecutorService when shutdown() is called.
How can I make sure that the TimerTask is stopped?
Thanks
use ExecuterService.submit() to get back Future object once the task is completed.
ExecutorService.Submit()
The method call TimerTask.cancel() should do the desired.
Your Runnable.run method could be designed like this:
public void run() {
pingTask = new PingTimerTask(...);
try {
...
} finally {
/* this code even gets executed when an exception
* (for example an *InterruptedException*) was thrown:
*/
pingTask.cancel();
}
}

sequential event processing via executorservice

I have an event queue to process. A thread adds events to the queue.
I have created a runnable Task that in the run method does all which is necessary to process the event.
I have declared an Executors.newCachedThreadPool(); and I execute each Task.
public class EventHandler {
private static final ExecutorService handlers = Executors.newCachedThreadPool();
public void handleNextEvent(AnEvent event){
handlers.execute(new Task(evt));
}
public class Task implements Runnable{
#Override
public void run() {
//Event processing
}
}
public AnotherClass{
public void passEvent(AnEvent evt)//This is called by another thread
{
EventHandler.handleNextEvent(evt);
}
}
My problem is that if I call execute of the executor, my code will get the next event and run next runnable via the executor.
My purpose is to process next event from queue only after previous task has ended.
How would I know that the previous task has finished or not so that I know I can call handleNextEvent again?
Is having some status field updated by the Task a good idea?
Thanks
Executors.newCachedThreadPool() will create new threads on demand, so it's not what you want. You want something like Executors.newSingleThreadExecutor(), which will process the events one at a time, and queue up the rest.
See javadoc:
Creates an Executor that uses a single worker thread operating off an unbounded queue. (Note however that if this single thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.) Tasks are guaranteed to execute sequentially, and no more than one task will be active at any given time.
I think Executors.newSingleThreadExecutor() and the submit() Method are the solution to your problem: http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorService.html

Categories

Resources