Message:frameworks\base\core\java\android\Os\Message.java
消息,其中包含了消息ID,消息处理对象(Handler)以及处理的数据等,由MessageQueue统一列队,终由Handler处理。
Handler:frameworks\base\core\java\android\Os\Handler.java处理者,负责Message的发送及处理。使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等。
MessageQueue:frameworks\base\core\java\android\Os\MessageQueue.java
消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。当然,存放Message并非实际意义的保存,而是将Message以链表的方式串联起来的,等待Looper的抽取。
Looper:frameworks\base\core\java\android\Os\Looper.java
消息循环,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue需要一个Looper。
关系图如下:
消息处理流程:
class LooperThread extends Thread { public Handler mHandler; public void run() { Looper.prepare(); // 创建Looper并与本线程绑定 【第一步】 mHandler = new Handler() { // 定义并实现Handler.handleMessage方法 【第二步】 public void handleMessage(Message msg) { // process incoming messageshere } }; Looper.loop(); // 启动Looper消息循环 【第三步】 } }
相关源代码如下:
public static void prepare() { prepare(true); } private static void prepare(booleanquitAllowed) { if (sThreadLocal.get() != null) { throw newRuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(newLooper(quitAllowed)); //新建一个looper对象,并保存到线程本地变量中 /// M: ALPS00297986 long instances =VMDebug.countInstancesOfClass(Looper.class, false); // check if the looper instance over alimit, it should has some leakage. if(100 < instances) { Log.e(TAG,"WARNING: The Looperclass instance count has over a limit(100). There should be some leakage ofLooper or HandlerThread."); Log.e(TAG,"Looper classinstance count = " + instances); Log.e(TAG,"Current ThreadName: " + Thread.currentThread().getName()); Thread.currentThread().getThreadGroup().list(); Thread.currentThread().dumpStack(); }//if /// M: ALPS00297986 } private Looper(boolean quitAllowed) { mQueue = new MessageQueue(quitAllowed); //新建一个消息队列 mThread = Thread.currentThread(); //保存当前线程 }
新建handler并初始化:
publicHandler() { this(null, false); } public Handler(Callback callback, booleanasync) { if (FIND_POTENTIAL_LEAKS) { final Class<? extendsHandler> klass = getClass(); if ((klass.isAnonymousClass() ||klass.isMemberClass() || klass.isLocalClass()) && (klass.getModifiers() &Modifier.STATIC) == 0) { Log.w(TAG, "The followingHandler class should be static or leaks might occur: " + klass.getCanonicalName()); } } mLooper = Looper.myLooper(); //获取当前线程的looper if (mLooper == null) { throw new RuntimeException( "Can't create handlerinside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; mCallback = callback; mAsynchronous = async; }
消息循环:
public staticvoid loop(){ final Looper me = myLooper(); if (me == null) { throw new RuntimeException("NoLooper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue; // Make sure the identity of thisthread is that of the local process, // and keep track of what that identitytoken actually is. Binder.clearCallingIdentity(); final long ident =Binder.clearCallingIdentity(); for (;;) { //dead loop Message msg = queue.next(); //might block if (msg == null) { // No message indicates thatthe message queue is quitting. return; } // This must be in a localvariable, 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); } /// M: MSG Logger Manager @{ if(!IS_USER_BUILD) { Printer msglogging =me.mMsgMonitorLogging; if (msglogging != null) { msglogging.println(">>>>> Dispatching to " +msg.target + " " + msg.callback +": " + msg.what); } if(MessageMonitorLogger.monitorMsg.containsKey(msg) ) { MessageMonitorLogger.MonitorMSGInfo monitorMsg =MessageMonitorLogger.monitorMsg.get(msg); if(MessageMonitorLogger.mMsgLoggerHandler.hasMessages(MessageMonitorLogger.START_MONITOR_PENDING_TIMEOUT_MSG,monitorMsg )) { Log.d("Looper", "RemoveMessages PENDING_TIMEOUT_MSG msg="+msg); MessageMonitorLogger.mMsgLoggerHandler.removeMessages(MessageMonitorLogger.START_MONITOR_PENDING_TIMEOUT_MSG,monitorMsg); try { if(monitorMsg.executionTimeout>100) { Message msg1 =MessageMonitorLogger.mMsgLoggerHandler.obtainMessage(MessageMonitorLogger.START_MONITOR_EXECUTION_TIMEOUT_MSG,monitorMsg); MessageMonitorLogger.mMsgLoggerHandler.sendMessageDelayed(msg1, monitorMsg.executionTimeout); } else { MessageMonitorLogger.monitorMsg.remove(msg); if(monitorMsg.executionTimeout !=MessageMonitorLogger.DISABLE_MONITOR_EXECUTION_TIMEOUT_MSG) throw newIllegalArgumentException("Execution timeout <100 ms!"); } } catch(Exception e) { Log.d(TAG,"Execution timeout exception "+e); } } } } /// M: MSG Logger Manager @} msg.target.dispatchMessage(msg);//对消息进行分发处理 if (logging != null) { logging.println("<<<<<Finished to " + msg.target + " " + msg.callback); } /// M: MSG Logger Manager @{ if(!IS_USER_BUILD) { Printer msglogging =me.mMsgMonitorLogging; if (msglogging != null) { msglogging.println("<<<<< Finished to " +msg.target + " " + msg.callback); } if(MessageMonitorLogger.monitorMsg.containsKey(msg) ) { MessageMonitorLogger.MonitorMSGInfo monitorMsg = MessageMonitorLogger.monitorMsg.get(msg); if(MessageMonitorLogger.mMsgLoggerHandler.hasMessages(MessageMonitorLogger.START_MONITOR_EXECUTION_TIMEOUT_MSG,monitorMsg )) { Log.d("Looper", "RemoveMessages EXECUTION_TIMEOUTmsg="+msg); MessageMonitorLogger.mMsgLoggerHandler.removeMessages(MessageMonitorLogger.START_MONITOR_EXECUTION_TIMEOUT_MSG,monitorMsg); MessageMonitorLogger.monitorMsg.remove(msg); } } } /// MSG Logger Manager @} // Make sure that during the courseof dispatching the // identity of the thread wasn'tcorrupted. final long newIdent =Binder.clearCallingIdentity(); if (ident != newIdent) { Log.wtf(TAG, "Threadidentity 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(); } }
将消息发送到消息队列:
private Message createMessage(Handlerhandler,String str) { Message msg =handler.obtainMessage(); Bundle data = new Bundle(); data.putString("message", str); msg.setData(data); return msg; }
为什么继承activity 之后不需要:
Looper.prepare() 和Looper.loop();
直接实现一个handler之后,就可以实现消息处理流程?
下图为activity的启动流程:
Activity是一个UI线程,运行于主线程中,Android系统在启动的时候会为Activity创建一个消息队列和消息循环(Looper)。详细实现请参考ActivityThread.java文件
Android应用程序进程在启动的时候,会在进程中加载ActivityThread类,并且执行这个类的main函数,应用程序的消息循环过程就是在这个main函数里面实现的
public final classActivityThread { ...... public static final void main(String[] args) { ...... Looper.prepareMainLooper(); ...... <span style="color:#ff0000;">ActivityThread thread = new ActivityThread();</span> thread.attach(false); ...... <span style="color:#ff0000;"> Looper.loop();</span> ...... thread.detach(); ...... } }
这个函数做了两件事情,一是在主线程中创建了一个ActivityThread实例,二是通过Looper类使主线程进入消息循环中
测试源码请参考:
http://download.csdn.net/detail/u010657219/8145063