一、消息循环过程
Android应用程序进程在启动的时候,会在进程中加载ActivityThread类,并且执行这个类的main函数,应用程序的消息循环过程就是在这个main函数里面实现的
public static void main(String[] args) {
。。。。。。
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
。。。。。。
Looper.loop();
}
首先看Looper.prepareMainLooper函数
// sThreadLocal.get() will return null unless you've called prepare().
static final ThreadLocal sThreadLocal = new ThreadLocal();
final MessageQueue mQueue;
final Thread mThread;
public static void prepareMainLooper() {
prepare(false);标注1
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();标注2
}
}
标注1:private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));标注3
}
标注3:private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
标注2:public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
然后看Looper.loop()函数:
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;标注4
......
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
......
msg.target.dispatchMessage(msg);标注5
......
msg.recycleUnchecked();标注6
}
}
标注4:MessageQueue对象Message队列
标注5:Message的target是Handler
标注6:回收Message
二、消息发送过程
ActivityManagerService通过调用ApplicationThread类的scheduleLaunchActivity函数通知应用程序,它可以加载应用程序的默认Activity了(ApplicationThread是ActivityThread的内部类)
private class ApplicationThread extends ApplicationThreadNative {
@Override
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
int procState, Bundle state, PersistableBundle persistentState,
List pendingResults, List pendingNewIntents,
boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.referrer = referrer;
r.voiceInteractor = voiceInteractor;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.persistentState = persistentState;
r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;
r.startsNotResumed = notResumed;
r.isForward = isForward;
r.profilerInfo = profilerInfo;
r.overrideConfig = overrideConfig;
updatePendingConfiguration(curConfig);
sendMessage(H.LAUNCH_ACTIVITY, r);
}
}
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
if (DEBUG_MESSAGES) Slog.v(
TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
+ ": " + arg1 + " / " + obj);
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
mH是Handler,Handler.sendMessage最终会调用sendMessageAtTime方法:
final MessageQueue mQueue;
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;标注7
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);标注8
}
public Handler(Callback callback, boolean async) {
mLooper = Looper.myLooper();
......
标注7:mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
标注8:private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;标注9:Handler发送的Message中的target都是Handler本身
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);标注10
}
标注9:Handler发送的Message中的target都是Handler本身
标注10:MessageQueue的enqueueMessage方法就已经将Message信息加入到消息队列中了
三、消息的处理
在标注5处获取Message的target也就是当前Handler(mH)对象,调用Handler的dispatchMessage方法,最终会调用mH的handlerMessage方法:
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;