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.
Related
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?
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 am little bit confused with multithreading in Android. I am aware we can achieve using AsyncTask and Handler. Generally when should we implement by extending Thread Class in Android? Can anyone give an example that we need to do it only by extending thread class but not with AsyncTask or Handler.
Consider a example app, we have a bouncing ball in an activity(forget the animation part), I need to change the color of the ball every 20 minutes, and I need to get the color code from the server and update the ball UI. Now how can I achieve this ? Can someone explain using AsyncTask or Handler and also only using Thread Class(without Asynctask or Handler)?
How should I handle downloading large payloads from server using services.
Thread
Long task in general
Invoke by thread.start() method
Triggered from any thread
Runs on its own thread
Manual thread management/code may become difficult to read
AsyncTask
Small task having to communicate with main thread
Invoke by execute() method
Triggered from main thread
Runs on worker thread
Must be executed and created from the main Thread
Service
Task with no UI,but should not use for long Task. Use Thread within service for long Task
Invoke by onStartService()
Triggered from any Thread
Runs On Main Thread
May block main(UI) thread
IntentService
Long task usually no communication with main thread if communication is needed then it is done by Handler or broadcast
Invoke via Intent
Triggered from Main Thread (Intent is received on main Thread and worker thread is spawned)
Runs on separate thread
Can't run task in parallel and multiple intents are Queued on the same worker thread.
Thread: Use it to separate long running computation from Main Thread ( UI Thread). If you don't need to update UI or send messages back to UI Thread, use it for long running tasks. But you don't really need to extend Thread and write your logic by overriding Thread methods. But still HandlerThread is effective compared to java Thread.
AsyncTask : it is designed to be a helper class around Thread and Handler and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few milli seconds at the most). Recommended for 5 milli seconds task execution.
Service: Use it to handle network transactions, play music, perform file I/O, or interact with a content provider, all from the background.
HandlerThread/Handler: A HandlerThread is effectively a long-running thread that grabs work from a queue, and operates on it. You can use it even to send results back to UI Thread via Handler of UI Thread.
Have a look at below posts for more details:
Asynctask vs Thread vs Services vs Loader
Handler vs AsyncTask vs Thread
Creating Background Service in Android
Android: Toast in a thread
An AsyncTask is basically a thread. It has 3 callBack methods(main) and the are executed in this order top to bottom:
1. onPreExecute()
2. doInBackground()
3. onPostExecute()
4. onProgressUpdate()
The onPreExecute() and onPostExecute() are running on the UI thread and doInBackground() is a separate thread as such. If you spawn a thread(not a AsyncTask), and try to set a property of a UI element from it, this will raise an exception saying: the original thread(the UI thread) which created the view can only modify it. So only the UI thread has these two properties:
Only it can add/modify the UI of the App
It cannot be blocked for more than 5 secs(ANR exception)
So to over come both these limitations in one go, we have AsyncTask, it can run resource consuming operations(network access, implementing gaming logic etc) in doInBackground(), and still provide ability to alter the UI from onPreExecute() and onPreExecute().
I think title itself says what the my question is...
AFAIK, in Java, when work of a Thread is completed i.e. run() method has completed executing, Thread itself will finish and dies.
So, When my Activity(I mean UI) is idle for a long time, what the UI thread will do? does it sleeps? or does it do any other work?
Thanks to all...
I believe the question is not really about Java threads in general, but about the Android "main thread" (also called the "UI thread").
To quote from the JavaDoc for the Android Handler:
When a process is created for your application, its main thread is
dedicated to running a message queue that takes care of managing the
top-level application objects (activities, broadcast receivers, etc)
and any windows they create. You can create your own threads, and
communicate back with the main application thread through a Handler.
This is done by calling the same post or sendMessage methods as
before, but from your new thread. The given Runnable or Message will
then be scheduled in the Handler's message queue and processed when
appropriate.
In other words: The main thread is responsible for dequeuing messages/runnables from a queue and processing them. That main thread is blocked while the queue is empty (since there is nothing for it to do). If you use a Handler that was created in the main thread, that Handler's messages and runnables will actually be added to the same queue used by the main thread. Normally, the main thread will run as long as the process does.
Note: An Android app can actually have multiple processes, and each one will have its own main thread. However, most Android apps will only have one process (and therefore one main thread).