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