上一篇文章(http://blog.youkuaiyun.com/chenyufei1013/article/details/6586456)中提到应用程序的管理模型。但是,并未作具体的解释,所以本文先把这一块内容稍许解释下,这对跟踪Android的Framework代码会有帮助。
- 主线程消息循环
- 概述
Android 2.3.5的实现中:
- 同一个进程中,只有一个JVM,一个ActivityThread.main。
- 每个java线程中,最多有一个ActivityThread和Looper。
- 每个Looper,可以有多个Handler与之对应。创建Handler的时所在的线程决定了该Handler和那个线程的Looper绑定。
- 可以通过Handler来获取消息和投递消息。
- 初始化Looper环境。
- 创建用于管理主线程的ActivityThread对象。除了ActivityThread之外还有一个类是ApplicationThread;可以理解为ApplicationThread是本进程的服务端,负责处理其它进程的请求的,最终将请求递交给ActivityThread,由ActivityThread来做具体的事情。此部分本节不作介绍。
- 初始化Activity运行环境,并通知相关的后台服务,比如ActivityManagerService。此部分本节不作介绍。
- 进入消息循环。
- 去初始化。此部分本节不作介绍。

具体参见下面的源码分析:
- 一个进程、一个JVM、一个ActivityThread.main
关于这个问题不作太多解析,牵扯到的源码比较多,具体的参考下面的连个调用序列即可。应用进程都是通过zygote进程fork出来的(启动应用的流程可以参考这里),zygote进程接收处理socket消息的循环为ZygoteConnection.run(),调用到ZygoteInit.main的过程为:
ZygoteConnection.run
ZygoteConnection.runOnce
Zygote.forkAndSpecialize // 此处仅fork和初始化
ZygoteConnection.handleChildProc // 此处便开始执行
RuntimeInit.zygoteInit
Process.invokeStaticMain
ZygoteInit.MethodAndArgsCaller
ZygoteInit.main // 此处可以和下面的栈接上。
ZygoteInit.main调用到Activity.onCreate的栈为(取自eclipse代码调试时的栈信息):
HelloOnDrawActivity.onCreate(Bundle) line: 14
Instrumentation.callActivityOnCreate(Activity, Bundle) line: 1123
ActivityThread.performLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2364
ActivityThread.handleLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2417
ActivityThread.access$2100(ActivityThread, ActivityThread$ActivityRecord, Intent) line: 116
ActivityThread$H.handleMessage(Message) line: 1794
ActivityThread$H(Handler).dispatchMessage(Message) line: 99
Looper.loop() line: 123
ActivityThread.main(String[]) line: 4203
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]
Method.invoke(Object, Object...) line: 521
ZygoteInit$MethodAndArgsCaller.run() line: 791
ZygoteInit.main(String[]) line: 549
NativeStart.main(String[]) line: not available [native method]
- 初始化Looper
初始化Looper的语句为Looper.prepareMainLooper()。该函数首先调用prepare():
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
ThreadLocal和Thread的关系可以简单描述如下,具体可以参见ThreadLocal.get()的代码。
1.同一个线程,不同的ThreadLocal,存储位置不同。
2.同一个ThreadLocal,在不同的线程中,存储位置不同。
此处由于sThreadLocal是static的,故可认为只有一个ThreadLocal,那么每个线程中,ThreadLocal.get到的都是同一份,即每个线程只能有一个Looper,可以通过Looper.myLooper()获取;Looper.getMainLooper()可以获取ActivityThread.main中的Looper。
然后是调用setMainLooper(myLooper());设置为main Looper。接下来设置标志位,若支持多进程,则允许main Looper退出。
if (Process.supportsProcesses()) {
myLooper().mQueue.mQuitAllowed = false;
}
- 进入消息循环
进入消息循环的语句为Looper.loop(),该函数主要是获取当前线程的消息队列,然后对每条消息调用如下函数:
msg.target.dispatchMessage(msg);
实际上是调用Handler的dispatchMessage函数;
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg); // 处理msg的callback
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) { // 处理Handler的callback
return;
}
}
handleMessage(msg); // 处理消息体。此处实际上是调用Handler子类的handleMessage函数。
}
}
- 获取、发送消息
若是要往消息循环中发送消息,可以通过Handler类,按如下步骤即可。
1.初始化Handler。初始化Handler的过程如下: 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; // 绑定消息队列
mCallback = null; // 没callback
2.获取消息。获取消息可以通过Handler.obtainMessage函数
3.发送消息。发送消息可以通过Handler.sendEmptyMessage等相关函数。
- 应用进程和ActivityManangerService之间的通信
应用进程和ActivityManangerService之间的通信是通过IBinder的,IBinder只是一种调用方式罢了,具体的调用内容都是定义在Framework中相关的类中的。IBinder是基于C/S模型的,既然是相互通信,自然应用程序既是服务端又是客户端。下面分别分析之:
1. 应用进程作为客户端当应用进程作为客户端时,两端的通信定义在文件ActivityManagerNative.java中。比如:ActivityThread的初始化方法attach中:
IActivityManager mgr = ActivityManagerNative.getDefault();
是通过ActivityManagerNative获取ActivityManagerService的代理对象ActivityManagerProxy的。
gDefault = asInterface(b);
asInterface方法会new一个新的ActivityManagerProxy对象返回给应用进程用。而ActivityManagerProxy中的方法都会调用transact方法,这个方法通过IBinder最终会调到ActivityManagerNative.onTransact方法中。由于ActivityManangerService继承自ActivityManagerNative,onTransact方法又会掉入ActivityManangerService中实现的IActivityManager接口中,从而完成应用程序对ActivityManangerService的调用。
2.应用进程作为服务端
这个过程和上面是类似的,只是它采用的通信类定义在ApplicationThreadNative.java中。当ActivityManangerService拿到ApplicationThreadProxy对象时,然后会通过IBinder调入了ApplicationThreadNative的onTransact方法中,最终调入了ApplicationThread方法中。跟踪ApplicationThread中的方法会发现它最终调用了如下语句:
mH.sendMessage(msg);
实际上是通过上面提到的mH的Handler往主线程的消息循环中发消息。比如:ApplicationThread.scheduleLaunchActivity的方法实际上是向主线程中发送H.LAUNCH_ACTIVITY消息。