HandlerThread详解

1 HandlerThread基本原理

  HandlerThread继承自Thread,它是一种可以使用Handler的Thread。它的实现很简单,就是在run方法中通过Looper.prepare()来创建消息队列,并通过Looper.loop()来开启消息循环。这样,我们就可以直接在HandlerThread中创建Handler了。HandlerThread的run方法如下所示:

 public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -;
}

  既然HandlerThread中已经有了消息循环,那么我们就可以在HandlerThread类或其子类中直接创建Handler对象,但是我们要记住一点:如果我们需要创建与该HandlerThread线程相关联的Handler的话,我们要使用Handler(Looper looper)构造方法,这样我们所创建的Handler对象才会与当前线程的消息循环相关联。在HandlerThread中,我们可以通过getLooper()方法获得Looper实例。

  从HandlerThread的实现上来看,它和普通Thread有显著不同,普通Thread主要在run方法中执行耗时任务,而HandlerThread在内部创建了消息队列,外界需要通过Handler的消息方式来通知HandlerThread执行一个具体任务。通常,一个普通的Thread线程也可以成为Looper线程,我们只需要为其创建消息队列并开启消息循环即可。看如下实现代码:

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();
}
}

我们可以根据不同应用场景选择不同的实现方式,不过既然Android已经提供了HandlerThread类,那我们在开发过程中可能会更倾向于使用该类完成耗时操作。

2 示例程序

  我们将通过一个简单示例程序来说明HandlerThread的用法。本示例程序中,我们向HandlerThread发送消息,然后HandlerThread返回该消息并显示到TextView上,在这个过程中我们通过sleep来模拟耗时操作。我们将创建一个继承自HandlerThread的类:CustomHandlerThread,

 public class CustomHandlerThread extends HandlerThread {
private static final String TAG = "CustomHandlerThread";
private static final int MSG_WHAT = 0x11;
private Handler mResponseHandler;
private Handler mHandler;
private Callback mCallback;
public CustomHandlerThread(Handler responseHandler, Callback callback){
super(TAG);
mHandler = new Handler();
mResponseHandler = responseHandler;
mCallback = callback;
} public void enqueTask(String str, TextView textView){
Log.i(TAG, "receive a str: " + str);
mHandler.obtainMessage(MSG_WHAT, str).sendToTarget();
}
public void prepareHandler(){
mHandler = new Handler(getLooper()){
@Override
public void handleMessage(final Message msg) {
try{
TimeUnit.SECONDS.sleep(2);
final String result = (String)msg.obj;
mResponseHandler.post(new Runnable() {
@Override
public void run() {
mCallback.onResult(result);
}
});
}catch (InterruptedException ie){
ie.printStackTrace();
}
}
};
} public interface Callback{
public void onResult(String result);
}
public void removeMsg(){
mHandler.removeMessages(MSG_WHAT);
} }

  我们先看enqueTask方法,该方法很简单,我们仅用它来接收从外部传来的参数(准确的说是消息内容),并且通过当前线程的Handler将消息发送到当前线程消息队列中,对该消息的处理是在prepareHandler()方法中完成的。在prepareHandler方法中,我们创建Handler实例,并且与当前线程的消息队列相关联,这通过Handler(Looper looper)构造方法完成。mResponseHandler.post方法会将Runnable对象添加到主线程的消息队列,该Runnable对象将会在该mResponseHandler所属的线程中执行,由于mResponseHandler是从主线程传过来的(稍后我们会看到具体实现),因此Runnable将会运行在主线程中。run方法中我们通过回调接口来传递结果。下面我们看下MainActivity中的处理:

 public class MainActivity extends Activity implements CustomHandlerThread.Callback{
private TextView mTextView; private CustomHandlerThread mCustomHandlerThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView)findViewById(R.id.textView); mCustomHandlerThread = new CustomHandlerThread(new Handler(), this);
mCustomHandlerThread.start();
mCustomHandlerThread.prepareHandler();
for(int i = 0; i < 10; i++){
mCustomHandlerThread.enqueTask("string"+i);
}
} @Override
public void onResult(String result) {
mTextView.setText(result);
} @Override
protected void onDestroy() {
super.onDestroy();
mCustomHandlerThread.removeMsg();
mCustomHandlerThread.quit();
}
}

上面代码很简单,我们创建CustomHandlerThread并传入Handler对象,该Handler对象是在主线程中创建的,因此与主线程消息队列相关联,创建HandlerThread对象后必须要调用start方法,此外,在调用enqueTask之前必须先调用prepareHandler方法,以免导致空指针异常(Handler还没创建?怎么能向消息队列发送消息呢?)。最后要注意的是,当Activity退出时,我们一定要通过quit方法结束HandlerThread的执行。

Android之HandlerThread的更多相关文章

  1. Android 开发 HandlerThread详解 转载

    转载请注明出处:http://blog.csdn.net/vnanyesheshou/article/details/75073307 对于Handler不太懂的可以参考我的这两篇文章: Androi ...

  2. Android开发——HandlerThread以及IntentService详解

    .HandlerThread Android API提供了HandlerThread来创建线程.官网的解释是: //Handy class for starting a new thread that ...

  3. Android中HandlerThread的使用及源代码解析

    关于Hanlder的基本使用能够參见博文<Android中Handler的使用>,假设想了解Handler.Looper.Thread等的相互关系以及内部实现原理能够參见博文<深入源 ...

  4. Android多线程—HandlerThread解析

    一.HandlerThread作用 1.实现多线程:在工作线程之后执行任务(比如一些耗时任务) 2.异步通信.消息传递:实现工作线程与主线程(UI线程)之间的通信,即将工作线程的执行结果传递给主线程, ...

  5. Android(八) HandlerThread

    1.Looper Looper used to run a message loop for a thread. Threads by default do not have a message lo ...

  6. Android HandlerThread 总结使用

    转载请标明出处:http://www.cnblogs.com/zhaoyanjun/p/6062880.html 本文出自[赵彦军的博客] 前言 以前我在 [Android Handler.Loop ...

  7. Android HandlerThread 的使用及其Demo (转)

    转自http://www.cnblogs.com/hnrainll/p/3597246.html 介绍 首先我们来看看为什么我们要使用HandlerThread?在我们的应用程序当中为了实现同时完成多 ...

  8. 【Android】用HandlerThread模拟AsyncTask功能(ThreadTask)

    前言 AsyncTask是个好东西,能处理绝大多数应用线程和更新UI的任务,由于其内部使用了静态线程池,如果你有一堆异步任务(例如全局定时更新数据.同一个Activity中多个AsyncTask同时执 ...

  9. Android HandlerThread 的使用及其Demo

    今天我们一起来学习下一个Android中比较简单的类HandlerThread,虽然它的初始化有点小麻烦. 介绍 首先我们来看看为什么我们要使用HandlerThread?在我们的应用程序当中为了实现 ...

随机推荐

  1. MVC应用程序请求密码的功能(二)

    MVC应用程序请求密码的功能(二) 在完成<MVC应用程序请求密码的功能(一)>http://www.cnblogs.com/insus/p/3471534.html之后,如果你照着做,所 ...

  2. Apache + Tomcat +mod_jk 实现集群

    实现效果:用apache 分发请求到tomcat中的对应的项目 环境说明: 操作系统:window7 Javasdk: 1.7 Apache: 2.2.14    (本地安装路径:D:\Apache2 ...

  3. C++内存中的封装、继承、多态(上)

    C++内存中的封装.继承.多态(上) 继我的上一篇文章:浅谈学习C++时用到的[封装继承多态]三个概念 此篇我们从C++对象内存布局和构造过程来具体分析C++中的封装.继承.多态. 一.封装模型的内存 ...

  4. K-Means算法

    K-Means算法 K-Means算法的输入N,K和一个size为N的向量组vector.输出K个两两互不相交的向量组.其本质是将给定的向量组划分成K个类别,使得同类别的向量相似度比较大,而不同类别的 ...

  5. iOS多线程的初步研究3

    iOS多线程的初步研究(三) 弄清楚NSRunLoop确实需要花时间,这个类的概念和模式似乎是Apple的平台独有(iOS+MacOSX),很难彻底搞懂(iOS没开源,呜呜). 官网的解释是说run ...

  6. 简单2步实现 asp.net mvc ckeditor 图片上传

    1.打开ckeditor 包下的  config.js,添加一句 配置(PS:ckeditor 很多功能都在该配置文件里配置),如下: config.filebrowserImageUploadUrl ...

  7. linux学习之linux的hostname修改详解《转》

    linux的hostname是一个kernel变量,可以通过hostname命令来查看本机的hostname.也可以直接cat /proc/sys/kernel/hostname查看. #hostna ...

  8. 性能测试工具比较:LoadRunner vs JMeter - 测试结果数据比较

    对web请求(HTTP/HTML)进行性能测试,确认请求响应时间.分别使用Loadrunner和JMeter进行测试,比较测试结果. 1.LoadRunner测试web请求响应时间 1.1  编制(录 ...

  9. Organic Solar Cells - Theory and Practice

    renewable engergy: Wind solar Tidal Wave Ocean Bio Etc. How much energy we gonna need as following y ...

  10. Run SPLAHS2 under SE mode on gem5在gem5的SE模式下,运行SPLASH2程序

    1.  安装相关的gem5,可以参考以前的博客. 2.  下载splash2编译好的软件 首先从gem5的官网下载已经编译成alpha指令集的splash2.下载地址:http://www.gem5. ...