当我需要某些内容异步时,例如长时间运行的任务或使用网络的逻辑,或出于任何原因,
启动新主题并运行它可以正常工作。
创建处理程序并运行它也可以。
有什么不同?我什么时候应该使用每一个?
使用Handler
而不是Thread
的优势/原因是什么?
PS。
- 为了这个问题,让我们忽略AsyncTask
。
- Handler().postDelayed
用例对我很清楚,对于这个问题,我们假设我需要立即启动任务。
答案 0 :(得分:162)
如果你正在做的事情是"沉重的"你应该在一个线程中做到这一点。如果你没有在它自己的线程中明确地启动它,那么它将在主(UI)线程上运行,这可能会引起用户的紧张或缓慢响应界面。
有趣的是,当您使用线程时,通常还可以使用Handler作为您正在启动的工作线程与主线程之间的通信方式。
典型的线程/处理程序交互可能如下所示:
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);
}
}
};
总的来说,带回家是你应该在任何时候使用线程,这可能是长时间运行或非常密集(即任何网络,文件IO,重型算术等)。
答案 1 :(得分:28)
Handler
和Thread
是两个不同的东西,但它们并不相互矛盾。您可以同时拥有Handler
和Thread
,实际上每个Handler
必须在Thread
中投放。
有关详细信息,您可能需要check out this article。
答案 2 :(得分:18)
Handler
在同一个Thread
上运行,Thread
在另一个线程上运行。
如果您需要在同一个线程上运行某些东西,通常是GUI元素或类似的东西,请使用处理程序。
如果你想保持主线程可以做其他事情,请使用线程。用于需要花费大量时间的任何事情。
答案 3 :(得分:13)
处理程序是后台和UI线程之间最好的通信方式。通常,处理程序与线程的消息队列相关联,它们用于发送消息并可运行到消息。
使用:强>
线程:在saperate(后台)线程中执行任务而不是UI线程。 (有助于解锁UI线程)
处理程序用于在UI和后台线程之间进行通信。
看看这个article
答案 4 :(得分:4)
如果您需要从新线程更新用户界面,则需要 与用户界面线程同步。
您可以使用android.os.Handler类或AsyncTasks类 这个。
Handler类可以更新用户界面。处理程序提供 用于接收Message或Runnable类的实例的方法。
您的线程可以通过sendMessage(Message msg)方法发布消息 或者通过sendEmptyMessage()方法。
...关于线程等的更多信息here(包括不同线程和同步机制的turorials以及何时使用什么)
答案 5 :(得分:2)
使用Handler而不是Thread的优点/原因是什么?
Handler允许您发送和处理与线程Runnable
关联的消息和MessageQueue
对象。每个Handler
实例都与一个线程和该线程的消息队列相关联。
当你创建一个新的Handler
时,它被绑定到创建它的线程的线程/消息队列 - 从那时起,它将消息和runnables传递给该消息队列并执行它们因为他们从消息队列中走出来。
Handler有两个主要用途:
如果你使用java线程,你必须自己处理一些事情 - 与主线程同步,取消线程等。
除非您使用ThreadPoolExecutor
或ExecutorService
API,否则此单个线程不会创建线程池。
(从您对Blackbelt答案的评论中获取此查询)
为什么不使用Executor?即使我确实想使用Handler来做到这一点,怎么样?
某些类型的工作可以简化为高度并行的分布式任务。由于这会产生大量的工作包,AsyncTask
和HandlerThread
不是合适的类。 AsyncTask
的单线程特性会将所有线程工作转换为线性系统。另一方面,使用HandlerThread
类需要程序员手动管理一组线程之间的负载平衡。
ThreadPoolExecutor是一个帮助程序类,可以简化此过程。此类管理一组线程的创建,设置其优先级,并管理这些线程之间的工作分配方式。随着工作负载的增加或减少,类会旋转或销毁更多线程以适应工作负载。
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);
有关详细信息,请参阅create-threadpool上的此开发者指南文章。
查看这篇文章,了解Handler
使用多个Runnable实例的用法。在这种情况下,所有Runnable
任务将在单个线程中运行。
答案 6 :(得分:1)
Handler
可与Thread
结合使用,以创建排队机制。您可以使用handler
在Thread
Looper
答案 7 :(得分:0)
如果您只需要在主线程之外单独执行一次任务,则使用Thread。如果您想重复执行任务,那么android提供了一种使线程保持活动状态并接收消息或Runnable对象以使用MessageQueue中的Looper处理它们的方法。