从源码中深入学习Handler,HandlerThread,MessageQueue,Looper。
来源:互联网 发布:java 对象流 编辑:程序博客网 时间:2024/05/16 19:32
今天在写项目时用到了HandlerThread,就顺便把Handler,MessageQueue,Looper都顺便复习整理了一下,写成博客,与大家分享,由于自己水平有限,难免理解的有些浅薄,有什么不合适或者不懂的地方欢迎留言询问,咱们一起探讨。
如果是对Handler一点都不了解的朋友,可以参考我的另一篇博客Handler:搭建UIThread&WorkerThread之间通信的桥梁
好了,下面我们进入正题。
HandlerThread其实就是一个Thread,只不过它初始化了相应的MessageQueue和Looper。这里听不懂没关系,我们继续往下看。
我们知道,如果是Handler,它初始化MessageQueue和Looper对象的方法是(下面的代码是需要用户写的)
new Thread(new Runable()){ @Override public void run() { new Handler(){ @Override public void handleMessage(Message msg) { Looper.prepare(); ...... //处理消息的代码 Looper.loop(); } } }}
而HandlerThread的run方法呢,是源码中写好的
public class HandlerThread extends Thread { int mPriority; //线程优先级 int mTid = -1; //线程的ID Looper mLooper; //该线程对应的Looper对象 public HandlerThread(String name) { //name 该线程的名字 super(name); mPriority = Process.THREAD_PRIORITY_DEFAULT; } //HandlerThread的另一个构造函数 public HandlerThread(String name, int priority) { super(name); mPriority = priority; } //下面是该线程的run()方法 @Override public void run() { mTid = Process.myTid(); Looper.prepare(); //重点:HandlerThread的run()方法调用了looper.prepare()方法,初始//化了Looper和MessageQueue,至于为什么,下面再讲解 synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop(); //重点:HandlerThread的run()方法调用了looper.loop()方法,建立了消 //息队列的循环 mTid = -1; }}
总结一下,就是HandlerThread比Handler+Thread的方式更方便,因为它自己已经初始化好了Looper和MessageQueue,用户直接调用handler.obtainMeaasge()发送消息,用handler.handleMessage()出息消息就行了,而且不用重写(Override)run()方法。
下面说一下为何通过Looper.prepare()可以初始化Looper和MessageQueue,还是让我们从源码中找答案。
先看怎样创建的Looper对象。
public static void prepare() { prepare(true); }//我们可以看到,调用Looper.prepare()方法后直接调用了prepare(true)//方法,而在该方法中很明显,new Looper(quitAllowed)新创建了一个//Looper对象, private static void prepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed));//创建Looper对象 }
再看怎样初始化的MessageQueue。
private Looper(boolean quitAllowed) { mQueue = new MessageQueue(quitAllowed);//重点:这里新创建了一个MessageQueue。 mRun = true; mThread = Thread.currentThread(); }
细心的朋友可能会问,Handler,Looper,MessageQueue是怎样绑定在一起的呢,我这里贴一下Looper类的几个成员变量,大家就明白了。
private static final String TAG = "Looper"; // sThreadLocal.get() will return null unless you've called prepare(). static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>(); private static Looper sMainLooper; // guarded by Looper.class final MessageQueue mQueue; //Looper对象的MessageQueue final Thread mThread; //Looper对象的Thread volatile boolean mRun; private Printer mLogging;
至于怎样绑定Handler对象,看了HandlerThread的用法,就一目了然了,下面讲解HandlerThread的基本用法。
handlerThread=new HandlerThread("HandlerThreadName->Login");handlerThread.start();handler(handlerThread.getLooper());handler=new Handler(handlerThread.getLooper()){//怎么样,绑定了吧,这是HandlerThread的最基本的用法,网上基本都是讲的这个。 @Override public void handleMessage(Message msg) { }}
**下面让我们进行一下最后的总结:
1.HandlerThread=MessageQueue+Looper+Thread
2.HandlerThread+Handler=MessageQueue+Looper+Thread+Handler
3.对于一个Thread,对应着一个唯一的MessageQueue,唯一的Looper,一个或者多个Handler对象。**
好了,想必大家已经明白的差不多了吧,由于本人水平实在有限,只能讲到这样了,有什么不明白的欢迎留言询问,大家一起探讨,今天就到这里了,再见。
- 从源码中深入学习Handler,HandlerThread,MessageQueue,Looper。
- 从源码中深入学习Handler,HandlerThread,MessageQueue,Looper。
- 从HandlerThread源码理清handler、looper与messageQueue之间的关系
- Message,MessageQueue,Looper,Handler,HandlerThread
- 从源码了解handler looper ,messageQueue思路
- 从源码了解handler looper ,messageQueue思路
- Looper,Handler, HandlerThread,Message,MessageQueue分析
- [Android]Handler-Looper-MessageQueue-Message、HandlerThread
- Handler Looper MessageQueue HandlerThread的那些事
- Handler、Looper、MessageQueue、Message、HandlerThread以及ActivityThread
- 深入理解Android消息机制,从源码解析Handler,Looper,MessageQueue
- 对Handler,Looper,messagequeue,HandlerThread的深入理解,Handler常见面试题
- Handler+Looper+MessageQueue深入详解
- Handler+Looper+MessageQueue深入详解
- Handler+Looper+MessageQueue深入详解
- Handler、Looper、MessageQueue深入解析
- Handler+Looper+MessageQueue深入详解
- Handler+Looper+MessageQueue深入详解
- UVA - 1585 Score
- android关于横竖屏切换
- 算法---全排列
- Swift UI专项训练35 UIAlertController
- VS2010添加类失败问题,弹出错误框,提示 CodeModel操作失败,无法访问标记数据库
- 从源码中深入学习Handler,HandlerThread,MessageQueue,Looper。
- 如何理解java的多态性
- android 各版本对应的sqlite版本
- 03-09-2015
- sort函数基础
- 深刻理解代理模式在java中如何优化系统性能
- 虚函数的作用
- Divein_day02_shell总结
- java 求标准差代码实现