Android:什么时候应该使用Handler(),什么时候应该使用Thread?

当我需要asynchronous运行的东西,比如长时间运行的任务或者使用networking的逻辑,或者出于任何原因,启动一个新线程并运行它可以正常工作。 创build一个处理程序并运行它也可以。 有什么不同? 我应该什么时候使用每一个? 使用Handler而不是Thread的优点/原因是什么?

PS。 – 为了这个问题,让我们忽略AsyncTask 。 – Handler().postDelayed用例对我来说很清楚,为了这个问题,我们假设我需要立即启动任务。

如果你正在做的是“沉重”,你应该在一个线程中做。 如果您没有在自己的线程中明确地启动它,那么它将在主(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); } } }; 

一般来说,拿回家就是你应该使用一个线程,任何时候你正在做一些可能是长时间运行或非常密集的工作(即任何networking,文件IO,重算术等)。

处理程序和线程真的是两回事。

必须创build一个线程才能执行长时间运行的作业。

Handler是一个非常方便的对象,用于在2个线程之间进行通信(例如:后台线程需要更新UI,可以使用Handler从后台线程向UI线程发送一些Runnable)。

所以你没有Handler或Thread之间的select。 用一个线程做重工作! (如果你的后台线程会触发一些工作在另一个线程中完成,你可以使用一个处理程序 – 大部分时间是UI线程)

HandlerThread是两个不同的东西,但它们并不矛盾。 您可以同时拥有一个Handler和一个Thread ,实际上每个Handler必须在一个Thread运行。

欲了解更多详情,你可能想看看这篇文章 。

在这里输入图像描述

Handler在同一个Thread运行, Thread在另一个线程上运行。

如果你需要在同一个线程上运行一些东西 ,通常是一个GUI元素或类似的东西,那就使用Handler

如果你想让主线程自由地做其他事情,可以使用线程 。 将此用于需要大量时间的任何事情。

处理程序是背景和UI线程之间沟通的最佳方式。 通常,处理程序与线程的消息队列相关联,它们用于发送消息并可以运行到消息。

使用:

线程:在比UI线程执行任务(背景)线程中执行任务。 (有助于取消屏蔽UI线程)

处理程序用于在UI和后台线程之间进行通信。

看看这篇文章

如果您需要从新线程更新用户界面,则需要与用户界面线程同步。

您可以使用android.os.Handler类或AsyncTasks类。

Handler类可以更新用户界面。 Handler提供了接收Message或Runnable类的实例的方法。

你的线程可以通过sendMessage(Message msg)方法或通过sendEmptyMessage()方法发布消息。

…关于线程等的更多信息(包括针对不同线程和同步机制的turorials以及何时使用什么)

使用处理程序而不是线程的优点/原因是什么?

Handler允许您发送和处理与线程的MessageQueue关联的Message和Runnable对象。 每个Handler实例都与单个线程和该线程的消息队列相关联。

当你创build一个新的Handler ,它绑定到正在创build它的线程的线程/消息队列 – 从这一点开始,它将把消息和可运行的消息传递给消息队列,并在消息出来时执行它们队列。

处理程序有两个主要用途:

  1. 将日程安排消息和Runnables作为将来的某个点执行
  2. 排队要在不同于自己的线程上执行的操作。

如果你使用java线程,你必须自己处理一些东西 – 与主线程同步,取消线程等。

除非使用ThreadPoolExecutorExecutorService API,否则此单个线程不会创build线程池。

(从你对Blackbelt的评论中回答这个问题)

为什么不使用Executor? 即使我真的想用Handler来做到这一点,怎么样?

参考: 线程性能文章

有一些types的工作可以降低到高度并行的分布式任务。 随着工作包的大量创build, AsyncTaskHandlerThread不是合适的类。 AsyncTask的单线程性质将把所有线程化的工作转化为线性系统。 另一方面,使用HandlerThread类将要求程序员手动pipe理一组线程之间的负载平衡。

ThreadPoolExecutor是一个帮助类,使这个过程更容易。 这个类pipe理一组线程的创build,设置它们的优先级,并pipe理这些线程之间的工作分配方式。 随着工作量的增加或减less,这个类会加速或破坏更多的线程以适应工作负载。

  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的开发者指南文章来获得更多的细节。

看看这个post使用Handler来运行多个Runnable实例。 在这种情况下,所有可运行任务将在单个线程中运行。

Android:在一个线程中吐司

Handler可以与Thread一起使用以创buildQueued机制。 你可以使用handlerThread Looper上发布一些东西