Is there any point in having multiple Handlers if they use the same Looper?
eg:
private Handler firstHandler = new Handler(Looper.getMainLooper());
private Handler secondHandler = new Handler(Looper.getMainLooper());
firstHandler.post(...);
secondHandler.post(...);
... they both post to the main thread, is that pointless to have the second one?
Thanks.
Is this an example of redundant use of Handlers?
Yes.
Quoted from the Docs:
A Handler allows you to send and process Message and Runnable objects
associated with a thread's MessageQueue. 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.
Those Handlers are sending messages to the same MessageQueue, so anyway the second one will run after the first one is done, meaning it's redundant.
Further more, The Handler is associated with the Thread it's created in by default. So if the Handler is created on the main thread you don't have to specify a Looper.
Yes both handlers are pointing to same "MessageQueue". More information can be had from the following link:
What is the purpose of Looper and how to use it?
Related
I have read on stack this:
When you use new Handler().post(r) (or Message), you added the
Runnable object to Looper and execute the code later in the same
thread.
this answer is accepted.
So now I have a dilemma, some guys on my last interview give me tip: if you want to run something in other thread and update from this new thread UI, lets use a Handler.
So Handler is new thread or not ?
Or maybe runnable in this thread works on other thread ?
Can somebody explain me ?
from official doc:
There are two main uses for a Handler: (1) to schedule messages and
runnables to be executed at some point in the future; and (2) to
enqueue an action to be performed on a different thread than your own.
Handler is not a new thread. It is just a mechanism to schedule some task to be done in the UI thread.
Creating/Posting to a Handler does not create new thread.
The Runnable posted to a Handler runs in the UI thread as soon as UI thread becomes free.
When you create a Runnable instance and post it, its reference gets stored and its run method will be called from the UI thread, at some point in the future. (You can also specify the delay using the method postDelayed().)
A Handler is associated with a Looper (and that Looper's thread). When you call new Handler() to create a new handler you're associating it with the Looper for the current thread (the thread where the current code is running).
Once you have this object, you can use it from another thread to report results, etc.
So for example, from a background thread you can call post() on a handler object that is associated with the UI thread. The Runnable you pass will be executed by that handler in its thread (not in the thread where the post() function was called) when the Handler gets to it.
For another source of info/details on loopers and handlers see https://developer.android.com/training/multiple-threads/communicate-ui
Here's the quote form Android documentation:
A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. 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.
There are two main uses for a Handler: (1) to schedule messages and runnables to be executed at some point in the future; and (2) to enqueue an action to be performed on a different thread than your own.
This part is quite important:
When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it
Handler is not a new thread and it can handle messages in a queue when you're passing new Runnables to the Looper thread, which process them. Each message can be processed in a separate thread or thread pool, when you explicitly do it. Otherwise, it will be processed in the thread, where Looper was created (it can be main/UI thread or other thread).
I was also confused about this mechanism some time ago, collected some links, resources and wrote sample app using Handler and Looper. You can check it here: https://github.com/pwittchen/android-looper-sample. Maybe you'll find it useful.
In Android we have Handler#post(Runnable) method to post some code to the main thread from another
Is it possible to make same thing in plain java (for instance while using swing)?
Explaining the question:
Assume we have two threads: ThreadA and ThreadB. Both are started already and running side-by-side. And ThreadB wants ThreadA to invoke some method (again, ThreadA is already running).
Addition optional question (you may not answer it):
And if it's possible, someone explain me how does exactly Handler do in Android. How it's able to post some code to MainThread? What is a purpose of the Looper?
Addressing your additional question:
You said "In Android we have Handler#post(Runnable) method to post some code to the main thread from another"
It is not exactly correct. You can 'post some code' from any thread A to any thread B provided that thread B is initialized as a Looper and the thread A has a reference to a Handler for the target thread B.
It is very convenient when you need to do something on the UI thread because the UI thread already has a Looper and you can retrieve it from nearly everywhere. The static method Looper.getMainLooper is a way to get a Looper for the main thread. If you initialize a Handler with this Looper you can post a Runnable or send a Message to it (though if you post Runnable it also gets wrapped into a Message) and it will be executed on the UI thread.
Looper, as the name hints, is basically running a non-terminating loop for a thread. The Looper has an associated MessageQueue which it constantly checks for new Messages. Via the Handler initialized with a Looper you can enqueue Messages on this thread. The Messages are processed in a sequential order, depending on the when field of a Message.
Here's a basic implementation of a Looper thread:
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
I suggest you read the Chapter 5 of Meike G.B. Android Concurrency. It will give you a comprehensive insight into the Looper/Handler framework. It is also great to browse the source code while you are reading, it is rather simple and self-explanatory.
Within Swing you would use
https://docs.oracle.com/javase/8/docs/api/javax/swing/SwingUtilities.html#invokeLater-java.lang.Runnable-
to run something on the main thread.
In general Java, an ExecutorService is like a thread pool and allows you to submit Runnable or Callable instances
https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html
However, if you aren't using an ExecutorService or Swing, there is no standard Java API to tell another thread to do something.
I am using the Unity game engine which also supports exporting to Android.
The engine uses multiple threads, including the UI thread and a separate scripting thread where all the user custom code is executing.
My scenario requires that i call some operation in a background thread, and i would like to marshal the result back to the main scripting thread.
I know the basics of the AsyncTask, Executor and Looper classes. Out of these, Looper seems like a good candidate since it allows setting up a queue and post back messages to a given thread (AsyncTask is "hardwired" to run the callback on the UI thread, which is not what i want here).
What is the proper way of achieving this?
There is 3 main ways to communicate with the UI thread :
Activity.runOnUiThread(Runnable)
View.post(Runnable)
Handlers
In your case, I advice you to create an Handler, as the 2 first solutions imply that you have a reference on your Activity or a View
Edit
If you want to use any thread in your app, just make sure a Looper has been set, and use an associated Handler
class YourLooperThread extends Thread
{
// make it accessible from the outside
private Handler handler;
#Override public void run()
{
Looper.prepare();
// Customize your handler, it has to be used in any thread which want to push a message in this thread's looper message Queue
handler = new Handler();
Looper.loop();
}
}
Be careful : all the other tasks you want to do in that thread must be done through the message queue, i.e posting a runnable in the handler. More information here : Handlers, MessageQueue, Looper, do they all run on the UI thread?
I have a Java thread that I start so it keeps listening to a socket (considering the a socket read is blocking a thread is needed).
After the Thread receives the data from the socket it needs to call a method from a class.
Now I have two options to do this:
Declare an interface that is passed to the Thread and implemented in a class. When the thread calls the interface method the implementing classes will run it.
Or I can pass the class instance to the Thread as a parameter and then call the class method.
But I wanted to know if the thread blocks while the method is running.
I suppose so but I'm not sure.
I wanted the thread to have a Socket event behavior. What I mean is to only be responsible for reading the data from the socket and fire functions in the main Class, the one that called the Thread.
Yes, the thread will block while executing the method, so it can not read from the socket at the same time. No information will be lost, the transfer only takes longer and you can get a socket timeout if the computation takes too long.
If your method takes much time to run, you should execute it in another worker thread. I recommend to use an Executor for that.
You have various options :
Make your class a child class of Thread (easier code but you'll merge functionnal part - your main code - with a technical aspect (extending the Thread))
Make your class implements the Runnable interface and start a new thread with that Runnable (i often do like that). So your main code still remains in a overriden run method, but the inheritance tree is up to you (your main class can extend one of your other class)
Keep separated your main code / the thread with two classes (one for your main code, one for the thread), linking the two at your will (remember that if you make an inner thread inside another class, the inner thread can use any final properties, for example).
As stated in other answers, anything happening in your run() method is of course blocking the execution.
As a sidenote, if you're going to deal with threads and sockets, i strongly suggest you to have a look at NIO frameworks like Netty that are just there for this kind of behavior : event driven client/server application through NewIO sockets.
As another sidenote, i often use this pattern :
start an acquisition thread that will catch the event ;
push them in a linkedblockingqueue (queue.offer()) ;
have another thread that shares the same linkedblockingqueue (with queue.take()) : this operation is blocking, the threads will be blocked as long as the queue is empty ;
This is a very simple way to have one thread as "producer", and one thread as "consumer". You can even have various consumers awaiting on the same queue.
But I wanted to know if the thread blocks while the method is running
Yes it does block.
If inside run you call a method to process something it doesn't matter if that is an interface etc as you ask it only matters what does the method actually do
In your case you have only 1 option.
Make sure that you return the control back to your socket listening thread asap.
This can happen by designing/mandating the processing class to handle the processing in a different thread.
Actually your problem is not something new. In event based designs there is the requirement to process the event as fast as possible so as to not block the event queue based flow.
And this is how I would recommend you to design arround. Not use any interface to interact with the listening thread but register an event listener(s).
When an event occurs i.e. your listening thread reads data, it will pass the data as event to your listener(s) at which point of course it will block.
Then you should start a new thread to do the processing and the listening thread can continue with its work
What is the different b/w running runnable inside handler new Handler().post(runnable) and running in Thread(runable) ?
Handler is used for communication between and coordinating threads. By creating a Handler, you bind it to the current thread. If you post a runnable to that Handler, it will be executed in that same thread.
Thread is Java's way to spawn new user-level threads. The runnable you pass it will be executed in that thread.
The two concepts are not mutually exclusive. You can use Handler with custom Threads.