Handler 机制学习之Handler、Looper、MessageQueue、Message之间的关系
来源:互联网 发布:博威软件 编辑:程序博客网 时间:2024/04/29 14:09
Handler、Looper、MessageQueue、Message之间的关系
一般创建一个Handler,会得到所在线程的Looper。如果所在线程没有Looper,则会出现运行时异常。
public Handler(Callback callback, boolean async) { 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(); //得到当前线程中的Looper if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; //当前Looper管理的MessageQueue mCallback = callback; mAsynchronous = async; }
主线程(UI线程)中都有一个Looper,在ActivityThread的main函数中:
public static void main(String[] args) { SamplingProfilerIntegration.start(); // CloseGuard defaults to true and can be quite spammy. We // disable it here, but selectively enable it later (via // StrictMode) on debug builds, but using DropBox, not logs. CloseGuard.setEnabled(false); Environment.initForCurrentUser(); // Set the reporter for event logging in libcore EventLogger.setReporter(new EventLoggingReporter()); Security.addProvider(new AndroidKeyStoreProvider()); Process.setArgV0("<pre-initialized>"); Looper.prepareMainLooper(); //创建Looper ActivityThread thread = new ActivityThread(); thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } AsyncTask.init(); if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } Looper.loop(); //循环 throw new RuntimeException("Main thread loop unexpectedly exited"); }Looper用于管理消息MessageQueue,在Looper中,有一个MessageQueue:
final MessageQueue mQueue;private Looper(boolean quitAllowed) { mQueue = new MessageQueue(quitAllowed); mThread = Thread.currentThread(); }
MessageQueue消息队列,维护一系列消息的先进先出。主要有消息进队列enqueueMessage,删除消息removeMessages,下一条消息next等。
Message即使发送的一条一条消息。
Handler通过sendMessage和post等方法,将一条消息放入到消息队列中,
public boolean sendMessageAtTime(Message msg, long uptimeMillis) { MessageQueue queue = mQueue; if (queue == null) { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); return false; } return enqueueMessage(queue, msg, uptimeMillis); } private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { msg.target = this; if (mAsynchronous) { msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis); }然后消息进入消息队列,消息队列中的消息会通过Looper循环取出分发:
public static void loop() { final Looper me = myLooper(); if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue; // Make sure the identity of this thread is that of the local process, // and keep track of what that identity token actually is. Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity(); for (;;) { Message msg = queue.next(); // might block //取出下一条消息 if (msg == null) { // No message indicates that the message queue is quitting. return; } // This must be in a local variable, in case a UI event sets the logger Printer logging = me.mLogging; if (logging != null) { logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); } msg.target.dispatchMessage(msg); //分发消息,通过对应消息的Handler来分发消息 if (logging != null) { logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); } // Make sure that during the course of dispatching the // identity of the thread wasn't corrupted. final long newIdent = Binder.clearCallingIdentity(); if (ident != newIdent) { Log.wtf(TAG, "Thread identity changed from 0x" + Long.toHexString(ident) + " to 0x" + Long.toHexString(newIdent) + " while dispatching to " + msg.target.getClass().getName() + " " + msg.callback + " what=" + msg.what); } msg.recycle(); } }Handler target; public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); //是Runnable对象 } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }private static void handleCallback(Message message) { message.callback.run(); //跑Runnable对象的run方法 }/** * Subclasses must implement this to receive messages. */ public void handleMessage(Message msg) { //跑自己写的方法 }
这样消息就会在相应的Handler中进行相应的处理了。
这样也就很好理解为什么可以在子线程中通过主线程的Handler来发送一条消息,最后被主线程的Handler中HandleMessage处理了。
因为最终都是这样:哪个Handler发的消息,就由自己来处理,而handler在哪个线程中,则使用当前线程的Looper,如果没有,可以自己创建一个。
Enjoy~今天(2015/10/13)看《深入理解Android卷I》,上面有两句话来总结它们之间的关系,看到的时候一下就觉得都顺了。
分享出来~
(1)Looper中有一个消息队列MessageQueue,里面存储的是一个个待处理的消息Message;
(2)Message中有一个Handler,这个Handler是用来处理Message的。
0 0
- Handler 机制学习之Handler、Looper、MessageQueue、Message之间的关系
- Message、Handler、MessageQueue、Looper之间的关系
- Message,Handler,MessageQueue,Looper之间的关系
- Message、Handler、MessageQueue、Looper之间的关系
- 学习Handler,Message,MessageQueue,Thread,Looper之间的关系
- Message/MessageQueue/Handler/Looper之间到关系
- Handler,Looper,Message,MessageQueue之间关系浅析
- Thread,Looper,Handler,Message,MessageQueue之间的关系
- Thread,Looper,Handler,Message,MessageQueue之间的关系
- Thread,Looper,Handler,Message,MessageQueue之间的关系
- Thread,Looper,Handler,Message,MessageQueue之间的关系
- 解析Handler,MessageQueue,Message,Looper之间的关系
- 描述Handler,Looper,MessageQueue,Message之间的关系
- Handler,Looper ,Message和MessageQueue 之间的关系
- Thread Looper MessageQueue Message Handler之间的关系
- android Message、Handler、MessageQueue、Looper之间的关系。
- Thread,Looper,Handler,Message,MessageQueue原理机制以及它们之间的关系
- Handler Looper Message MessageQueue 的关系
- 优化数据页面(28)——不打印颜色和底纹
- 22. jQuery 遍历 - 同胞
- MFC中App,Doc,MainFrame,View各指针的互相获取
- UE4 Reducing APK Package size
- 程序员面试金典2.4:给定值x为基准将链表分割成两部分
- Handler 机制学习之Handler、Looper、MessageQueue、Message之间的关系
- table 删除某行
- FreeMarker的简单使用
- 在myeclipse中java @override 报错处理
- Javascript
- 查询ORACLE表空间或者数据文件每次扩展大小
- dojod自定义属性
- magicsuggest 多选以及带搜索功能的下拉框
- 一个绚丽的loading动效分析与实现!