问题
When I need something to run asynchronously, such as a long running task or a logic that uses the network, or for whatever reason,
Starting a new Thread and running it works fine.
Creating a Handler and running it works as well.
What's the difference? When should I use each one?
What are the advantages / reasons to use a Handler
and not a Thread
?
PS.
- For this question's sake, let's ignore AsyncTask
.
- Handler().postDelayed
use case is clear to me, for this question's sake let's assume I need the task to start immediately.
回答1:
If whatever you are doing is "heavy" you should be doing it in a Thread. If you do not explicitly start it in its own thread, then it will run on the main (UI) thread which may be noticeable as jittery or slow to respond interface by your users.
Interestingly when you are using a thread it is often useful to also use a Handler as a means of communication between the work thread that you are starting and the main thread.
A typical Thread/Handler interaction might look something like this:
Handler h = new Handler(){
@Override
public void handleMessage(Message msg){
if(msg.what == 0){
updateUI();
}else{
showErrorDialog();
}
}
};
Thread t = new Thread() {
@Override
public void run(){
doSomeWork();
if(succeed){
//we can't update the UI from here so we'll signal our handler and it will do it for us.
h.sendEmptyMessage(0);
}else{
h.sendEmptyMessage(1);
}
}
};
In general though, the take home is that you should use a Thread any time you are doing some work that could be long running or very intensive (i.e. anything network, file IO, heavy arithmatic, etc).
回答2:
Handler and Thread are really 2 different things.
A thread must be created to execute long running jobs.
A Handler is very convenient object to communicate between 2 threads (for instance : a background thread need to update the UI. You can use a Handler to post some Runnable from your background thread to the UI thread).
So you don't have the choice between Handler or Thread. Use a thread to do heavy jobs! (you can use a Handler if your background thread will trigger some job to be done in another thread - most of the time the UI thread)
回答3:
Handler
and Thread
are two different things, but they do not contradict each other. You can have a Handler
and a Thread
at the same time and actually each Handler
must be running in a Thread
.
For more details, you may want to check out this article.
回答4:
A Handler
runs on the same Thread
, a Thread
runs on a different thread.
Use a Handler if you need to run something on the same thread, usually a GUI element or something like that.
Use a Thread if you want to keep the main thread free to do other things. Use this for anything that takes a significant amount of time.
回答5:
Handlers are the best way of communication between the background and UI thread. Generally Handlers are associated with message Queue of a Thread and they are used to send messages and runnable to the Message.
USE:
Thread: To do tasks in saperate(Background) thread than UI thread. (helps to unblock the UI thread)
Handler Used to communicate between the UI and Background thread.
Have a look at this article
回答6:
If you need to update the user interface from a new Thread, you need to synchronize with the user interface thread.
You can use the android.os.Handler class or the AsyncTasks class for this.
The Handler class can update the user interface. A Handler provides methods for receiving instances of the Message or Runnable class.
You thread can post messages via the sendMessage(Message msg) method or via the sendEmptyMessage() method.
... more info here about threads etc. (includes turorials for the different threading and sync mechanisms and when to use what)
回答7:
What are the advantages / reasons to use a Handler and not a Thread?
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:
- 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 use java threads, you have to handle somethings on your own - synchronizing with main thread, cancelling a thread etc.
This single Thread does not create a thread pool unless you use ThreadPoolExecutor
or ExecutorService
API.
(Taken this query from your comments on Blackbelt answer)
Why not use an Executor? and even if I did want to use a Handler to do that, how?
Reference : Thread Performance article
There are certain types of work that can be reduced to highly parallel, distributed tasks. With the sheer volume of work packets this creates, AsyncTask
and HandlerThread
aren’t appropriate classes. The single-threaded nature of AsyncTask
would turn all the threadpooled work into a linear system. Using the HandlerThread
class, on the other hand, would require the programmer to manually manage load balancing between a group of threads.
ThreadPoolExecutor is a helper class to make this process easier. This class manages the creation of a group of threads, sets their priorities, and manages how work is distributed among those threads. As workload increases or decreases, the class spins up or destroys more threads to adjust to the workload.
BlockingQueue workQueue= new LinkedBlockingQueue<Runnable>(100); // Work pool size
ThreadPoolExecutor executor = new ThreadPoolExecutor(
Runtime.getRuntime().availableProcessors(), // Initial pool size
Runtime.getRuntime().availableProcessors(), // Max pool size
1, // KEEP_ALIVE_TIME
TimeUnit.SECONDS, // KEEP_ALIVE_TIME_UNIT
workQueue);
You can refer to this developer guide article on create-threadpool for more details.
Have a look at this post for usage of Handler
to run multiple Runnable instances. In this case, all Runnable
tasks will run in a single Thread.
Android: Toast in a thread
回答8:
Handler
can be used in conjunction with Thread
in order to create a Queued mechanism. Uou can use the handler
to post something on the Thread
Looper
来源:https://stackoverflow.com/questions/13954611/android-when-should-i-use-a-handler-and-when-should-i-use-a-thread