Android-初识Handler,Looper,Message(-) 源码
2011-11-20 14:26
316 查看
本文只是表面的带大家浏览下Handler,Looper,Message的源码
android的消息处理有三个核心类:Looper,Handler和Message。其实还有一个Message Queue(消息队列),
异步处理大师 Handler:
什么是handler?handler扮演了往MQ上添加消息和处理消息的角色(只处理由自己发出的消息),即通知MQ它要执行一个任务(sendMessage),并在loop到自己的时候执行该任务(handleMessage),整个过程是异步的。handler创建时会关联一个looper,默认的构造方法将关联当前线程的looper,不过这也是可以set的。默认的构造方法:
当然这只是Handler的一个构造方法。Handler本身有四个构造函数,其他其他的三个你可以通过查看源码来解析,大致雷同。
Handler发送消息
有了handler之后,我们就可以使用
Post发送的形式
sendMessage(Message)形式
从源码中我们中我们可以很清晰的看到无论是用psot(Runnable)还是使用sendMessage(Message)方法,最后他们都会调用到同一个方法压入都一个队列中去。
Handler处理消息
那handler如何处理消息。消息的处理是通过核心方法是通过dispatchMessage(Message)来进行处理的,源码如下:
封装任务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构造:
以上就是对Handler和Message还有Looper的源码的表面认识
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的消息处理机制(图+源码分析)——Looper,Handler,Message
- Android单线程模型中Message、Handler、Message Queue、Looper之间的关系---附实例源码
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- [转载]android的消息处理机制(图+源码分析)——Looper,Handler,Message
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- (消息处理机制)Android的消息处理机制(图+源码分析)——Looper,Handler,Message
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- android的消息处理机制(图+源码分析)——Thread,Looper,MessageQueue,Message,Handler之间的关系
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- Android Handler、Looper、MessageQueue以及Message源码分析
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- android的消息处理机制(图文+源码分析)—Looper/Handler/Message
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- android的消息处理机制(图+源码分析)——Looper,Handler,Message