Android源码分析 — Hander消息机制
本篇记录Hanlder消息机制的关键节点代码
以下为源码:
Activity中的消息机制是在ActivityThread的main方法中初始化的,但注意的是ActivityThread并非继承字Thread。
public static void main(String[] args) {
SamplingProfilerIntegration.start();
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
EventLogger.setReporter(new ActivityThread.EventLoggingReporter());
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
AsyncTask.init();
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
存储消息,handler将Message存放到MessageQueue中
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (this.mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
具体的存入队列的方法,通过指明其next的值,指明message存入队列的位置
final boolean enqueueMessage(Message msg, long when) {
if (msg.isInUse()) {
throw new AndroidRuntimeException(msg + " This message is already in use.");
} else if (msg.target == null) {
throw new AndroidRuntimeException("Message must have a target.");
} else {
boolean needWake;
synchronized(this) {
if (this.mQuiting) {
RuntimeException e = new RuntimeException(msg.target + " sending message to a Handler on a dead thread");
Log.w("MessageQueue", e.getMessage(), e);
return false;
}
msg.when = when;
Message p = this.mMessages;
if (p != null && when != 0L && when >= p.when) {
needWake = this.mBlocked && p.target == null && msg.isAsynchronous();
while(true) {
Message prev = p;
p = p.next;
if (p == null || when < p.when) {
msg.next = p;
prev.next = msg;
break;
}
if (needWake && p.isAsynchronous()) {
needWake = false;
}
}
} else {
msg.next = p;
this.mMessages = msg;
needWake = this.mBlocked;
}
}
if (needWake) {
this.nativeWake(this.mPtr);
}
return true;
}
}
取消息,通过不断的循环从队列中取出消息,并根据message关联的target,也就是handler,将消息分发出去
public static void loop() {
Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
} else {
MessageQueue queue = me.mQueue;
Binder.clearCallingIdentity();
long ident = Binder.clearCallingIdentity();
while(true) {
Message msg = queue.next();
if (msg == null) {
return;
}
Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what);
}
msg.target.dispatchMessage(msg);
if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}
long newIdent = Binder.clearCallingIdentity();
if (ident != newIdent) {
Log.wtf("Looper", "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();
}
}
}
那既然消息是在主线程不断的轮询读取的,而我们activity的生命周期都是在主线程执行的,为什么不会卡死
public void handleMessage(Message msg) {
ActivityThread.ActivityClientRecord r;
switch(msg.what) {
case 100:
Trace.traceBegin(64L, "activityStart");
r = (ActivityThread.ActivityClientRecord)msg.obj;
r.packageInfo = ActivityThread.this.getPackageInfoNoCheck(r.activityInfo.applicationInfo, r.compatInfo);
ActivityThread.this.handleLaunchActivity(r, (Intent)null);
Trace.traceEnd(64L);
break;
case 101:
Trace.traceBegin(64L, "activityPause");
ActivityThread.this.handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
this.maybeSnapshot();
Trace.traceEnd(64L);
break;
.
.
.
case 142:
ActivityThread.this.handleUnstableProviderDied((IBinder)msg.obj, false);
}
}
因为activity的生命周期就是通过handler接收到的消息调用的,所以不会卡死