Android源码学习(1) Handler
2017-10-08 22:55
375 查看
Handler的实例化
在安卓开发中,经常会用到Handler将任务提交到指定线程(例如主线程)去执行或者让其延迟执行。Handler的构造函数有多种重载形式,但最终都调用到如下两种之一:public Handler(Callback callback, boolean async) { mLooper = Looper.myLooper(); if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; mCallback = callback; mAsynchronous = async; } public Handler(Looper looper, Callback callback, boolean async) { mLooper = looper; mQueue = looper.mQueue; mCallback = callback; mAsynchronous = async; }
可以看到:这两个构造函数的区别只是Looper的获取方式不一样,当未指定Looper时,Handler内部会通过Looper.myLooper()静态方法,获取当前线程的Looper。我们往Handler上发送的Message或者Runnable正是由这个Looper(或该Looper的线程)负责处理的。我们可以通过Looper.getMainLooper()获取主线程的Looper。
发送Message或者Runnable
调用post、postAtTime、postDelayed提交Runnable,调用sendMessage、sendEmptyMessage、sendMessageDelayed、sendEmptyMessageDelayed、sendMessageAtTime、sendEmptyMessageAtTime发送Message,最终都调用到sendMessageAtTime:1 public boolean sendMessageAtTime(Message msg, long uptimeMillis) { 2 MessageQueue queue = mQueue; 3 if (queue == null) { 4 RuntimeException e = new RuntimeException( 5 this + " sendMessageAtTime() called with no mQueue"); 6 Log.w("Looper", e.getMessage(), e); 7 return false; 8 } 9 return enqueueMessage(queue, msg, uptimeMillis); 10 } 11 12 private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { 13 msg.target = this; 14 if (mAsynchronous) { 15 msg.setAsynchronous(true); 16 } 17 return queue.enqueueMessage(msg, uptimeMillis); 18 }
也就是说,提交的Runnable最终会被包装成Message,此时Message的callback字段将指向该Runnable。所有提交的Message都将会被插入名为mQueue的有序队列中,排序的依据便是传入的uptimeMillis(该值在enqueueMessage操作中会被赋给Message的when字段)。MessageQueue使用生产者-消费者模式,post*和send*产生的消息,最终会被Looper消费。(第2行中将mQueue赋给局部变量queue再通过改变访问mQueue,显然是出于多线程并发的安全性考虑)
使用postAtFrontOfQueue、sendMessageAtFrontOfQueue可以分别提交Runnable和Message到mQueue的队首,该Runnable或者Message将在Looper的下次循环中处得到处理。
使用removeCallbacks、removeMessages、removeCallbackAndMessages可以移除掉已经提交的Runnable或者Message。
消息处理
Handler通过dispatchMessage处理往其发送的消息:public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } } private static void handleCallback(Message message) { message.callback.run(); } public void handleMessage(Message msg) { }
如果是Runnable,将直接执行;如果是普通的Message,将交由handlMessage进行处理。自定义Handler时,通过重写handlMessage进行具体处理。
相关文章推荐
- Android源码学习(4) Handler之ThreadLocal
- 新手学习android源码(一) 学习Handler,Looper,MessageQueue
- Android学习心得(24) --- Android Handler消息机制源码分析
- Android开发学习之路-Handler消息派发机制源码分析
- Android Handler体系部分源码学习
- android消息处理机制学习(三)-Handler,Message,MessageQueue,Looper源码分析
- android 消息系统Handler、MessageQueue、Looper源码学习
- Android源码学习(3) Handler之MessageQueue
- Android源码学习(2) Handler之Looper
- Android源码学习之四-ActivityGroup是如何对嵌入的Activitys进行管理的
- android源码学习之animation1
- 第一次学习Android(晒源码)
- Mars Android视频学习笔记——01_14/15_Handler的使用
- Android源码学习之八—系统启动过程
- android学习----Handler使用
- Android 之 handler 学习
- Android源码学习之七—传感器的背后
- Android Animation学习笔记--附带源码
- Android Animation学习笔记--附带源码
- Android源码学习之六——ActivityManager框架解析