Android-初识Handler,Looper,Message(-) 源码
来源:互联网 发布:淘宝企业采购 编辑:程序博客网 时间:2024/05/21 11:11
本文只是表面的带大家浏览下Handler,Looper,Message的源码
android的消息处理有三个核心类:Looper,Handler和Message。其实还有一个Message Queue(消息队列),
异步处理大师 Handler:
什么是handler?handler扮演了往MQ上添加消息和处理消息的角色(只处理由自己发出的消息),即通知MQ它要执行一个任务(sendMessage),并在loop到自己的时候执行该任务(handleMessage),整个过程是异步的。handler创建时会关联一个looper,默认的构造方法将关联当前线程的looper,不过这也是可以set的。默认的构造方法:
public class handler { final MessageQueue mQueue; // 关联的MQ final Looper mLooper; // 关联的looper final Callback mCallback; // 其他属性 public Handler() { if (FIND_POTENTIAL_LEAKS) { // 没看懂,直接略过,,, final Class<? extends Handler> klass = getClass(); if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && (klass.getModifiers() & Modifier.STATIC) == 0) { Log.w(TAG, "The following Handler class should be static or leaks might occur: " + klass.getCanonicalName()); } } // 默认将关联当前线程的looper mLooper = Looper.myLooper(); // looper不能为空,即该默认的构造方法只能在looper线程中使用
//UI主线程中默认带有一个Looper if (mLooper == null) { throw new RuntimeException(//不能在没有Looper的线程上创建Handler, "Can't create handler inside thread that has not called Looper.prepare()"); } // 重要!!!直接把关联looper的MQ作为自己的MQ,因此它的消息将发送到关联looper的MQ上 mQueue = mLooper.mQueue; mCallback = null; } // 其他方法 }
当然这只是Handler的一个构造方法。Handler本身有四个构造函数,其他其他的三个你可以通过查看源码来解析,大致雷同。
Handler发送消息
有了handler之后,我们就可以使用 post(Runnabl),sendMessage(Message)
这些方法向MQ上发送消息了。光看这些API你可能会觉得handler能发两种消息,一种是Runnable对象,一种是message对象,这是直观的理解,但其实post发出的Runnable对象最后都被封装成message对象了,见源码:
Post发送的形式
public final boolean post(Runnable r){//使用Post发送消息 return sendMessageDelayed(getPostMessage(r), 0);}
private final Message getPostMessage(Runnable r) {//把一个Runnable包转成一个Message Message m = Message.obtain(); m.callback = r; return m;}
public final boolean sendMessageDelayed(Message msg, long delayMillis){ if (delayMillis < 0) { delayMillis = 0; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);}
public boolean sendMessageAtTime(Message msg, long uptimeMillis){ boolean sent = false; MessageQueue queue = mQueue; if (queue != null) {/*该handler对象,这确保了looper执行到该message时能找到处理它的handler,直白点就是ABC三个Handler发送消息,最终执行的时候Message消息也是由他们本身来执行,而不会发生A接受到B发送的Message之类的情况*/ msg.target = this;//sent = queue.enqueueMessage(msg, uptimeMillis);//压入消息队列 }else { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); } return sent;}sendMessage(Message)形式
public final boolean sendMessage(Message msg){ return sendMessageDelayed(msg, 0);}public final boolean sendMessageDelayed(Message msg, long delayMillis){ if (delayMillis < 0) { delayMillis = 0; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); }从源码中我们中我们可以很清晰的看到无论是用psot(Runnable)还是使用sendMessage(Message)方法,最后他们都会调用到同一个方法压入都一个队列中去。
Handler处理消息
那handler如何处理消息。消息的处理是通过核心方法是通过dispatchMessage(Message)来进行处理的,源码如下:
public void dispatchMessage(Message msg) { if (msg.callback != null) {//post(Runnable)形式最终调用到这个方法 handleCallback(msg); } else {/* 这种方法允许让activity等来实现Handler.Callback接口或者构造Handler(Callback,避免了自己编写handler重写handleMessage方法*/ if (mCallback != null) {
if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg);//优先等级最低的就是 重写HandlerMessage方法了 } }封装任务Message
Message的源码中没有特别的方法,对于Message我们应该记住下面的几个知识点(等待大家补充)
1.尽管我们可以直接instance一个Message,但我们最好通过Message.obtain()来从消息池中获得空消息对象,以节省资源。
2.如果你的message只需要携带简单的int信息,请优先使用Message.arg1和Message.arg2来传递信息,这比用Bundle更省内存
3.擅用message.what字段表示code,即这个消息具体是什么类型的消息.每个what都在其handler的namespace中,我们只需要确保将由同一个handler处理的消息的what属性不重复就可以.相当于判别类型
4.message.When 它大小由小到大排列, 排在最前面的消息会首先得到处理,因此可以说消息队列并不是一个严格的先进先出的队列.
5.message.target 确定了最终你执行的时候由那个Handler来执行这个Message。一般来说谁压入队列就让谁在抽取出来的时候去执行。通过上面的源码我们可以查询到
Looper管道哥
首先明确一点Activity本身在启动的时候默认给了他一个Looper
Looper构造:
private Looper() { mQueue = new MessageQueue();//初始化Looper的时候的我们就给这个Looper配了一个MQ队列,一一对应 mRun = true; mThread = Thread.currentThread();//绑定他所属的线程 }// 我们调用该方法会在调用线程的TLS中创建Looper对象 public static final void prepare() { if (sThreadLocal.get() != null) { // 试图在有Looper的线程中再次创建Looper将抛出异常 throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper()); }public static final void loop() { Looper me = myLooper();//从该线程中取出对应的looper对象 MessageQueue queue = me.mQueue;//取消息队列对象... while (true) { Message msg = queue.next(); // might block 这个方法还不是很懂。出去一个待处理的Message //if (!me.mRun) { // break; //} if (msg != null) { if (msg.target == null) { // No target is a magic identifier for the quit message. return; } if (me.mLogging!= null) me.mLogging.println( ">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what ); msg.target.dispatchMessage(msg); //消息的抽取。最终的施行执行方法 if (me.mLogging!= null) me.mLogging.println( "<<<<< Finished to " + msg.target + " " + msg.callback); msg.recycle(); } } }以上就是对Handler和Message还有Looper的源码的表面认识
- Android-初识Handler,Looper,Message(-) 源码
- Android Looper、Handler、Message源码解析
- Android源码浅析: Message/Handler/MessageQueue/Looper
- Android Handler,Looper,Message
- Android - Looper / Handler / Message
- Android Handler Message Looper
- Android Handler 、 Looper 、Message
- Handler Looper Message源码研究
- Handler Looper Message源码研究
- Handler,message,Looper源码解析
- Handler-Looper-Message源码分析
- Handler、Looper、Message源码解析
- Android处理程序:Handler Looper Message源码研究
- Android处理程序:Handler Looper Message源码研究
- Android消息传递源码理解。Handler,Looper,MessageQueue,Message
- 深入源码解析Android中的Handler,Message,MessageQueue,Looper
- Android 消息机制 - Handler, Looper, Message, MessageQueue 的源码分析
- 深入源码解析Android中的Handler,Message,MessageQueue,Looper
- C#有关Session 操作的几个误区
- UIPageControl自定义点的颜色
- 基于活动的SDK:Appssavvy进军移动广告市场的“法宝”
- 在ASP.NET中使用Session常见问题集锦
- 使用Java混淆工具yguard
- Android-初识Handler,Looper,Message(-) 源码
- Android 的 Recovery 模式分析
- usb gadget 网卡和u盘安装
- Android 内存泄漏调试
- response.setHeader()的用法
- 云
- Android调试工具及方法
- Android 信号处理面面观 之 概述
- ATME16 定时器1实现电子钟表