首页 > 代码库 > 【内核研究】处理者_Handler
【内核研究】处理者_Handler
尽管MessageQueue提供了直接读/写的函数接口,但对于程序员来说,一般不直接读/写消息队列。之前了解到,在Looper.loop()函数中,当取出消息后,会回调msg.target对象的handleMessage()函数,而msg.target的类型正是Handler。
/** * Run the message queue in this thread. Be sure to call * {@link #quit()} to end the loop. */ public static final void loop() { Looper me = myLooper(); MessageQueue queue = me.mQueue; while (true) { Message msg = queue.next(); // might block //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类向消息队列中发送消息,并重载Handler类的handleMessage()函数添加消息处理代码。
Handler对象只能添加到有消息队列的线程中,否则会发生异常。以下代码是Handler类的构造函数:
/** * Default constructor associates this handler with the queue for the * current thread. * * If there isn‘t one, this handler won‘t be able to receive messages. */ 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()); } } 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 = null; }注意这句代码:
mLooper = Looper.myLooper(); if (mLooper == null) { throw new RuntimeException( "Can‘t create handler inside thread that has not called Looper.prepare()"); }由以上代码可以得出结论,在构造Handler对象前,必须已经执行过Looper.prepare(),但prepare()不能被执行两次。下面是Looper.prepare()的代码:
/** Initialize the current thread as a looper. * This gives you a chance to create handlers that then reference * this looper, before actually starting the loop. Be sure to call * {@link #loop()} after calling this method, and end it by calling * {@link #quit()}. */ public static final void prepare() { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper()); }创建Handler对象可以在执行Looper.loop()函数之前,也可以在执行之后。
在以往的应用程序开发中,一般在Activity的初始化代码中添加Handler对象,事实上,在Activity对象被构造前,Activity所在的线程已经执行了Looper.prepare()函数。具体可查看下面的链接。
http://blog.csdn.net/manoel/article/details/39499747
一个线程中可以包含多个Handler对象。在Looper.loop()函数中,不同的Message对应不同的Handler对象,从而回调不同的handleMessage()函数。
【内核研究】处理者_Handler
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。