Android: When should I use a Handler() and when should I use a Thread?

情到浓时终转凉″ 提交于 2019-12-17 05:24:07

问题


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:

  1. To schedule messages and Runnables to be executed as some point in the future
  2. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!