一、概述
由《源码分析 — ActivityThread(一)之main()何时被调用》一文,我们知道了
ActivityThread.main()
被调用的时机;
本文对以下几个问题进行分析:
- 在
ActivityThread.main()
方法中到底做了些什么操作呢?- 类
ApplicationThread
- 类
H
- 类
ActivityThread
源码版本: Andoroid 23
涉及到的知识点:
- 《源码分析 — Handler机制线程间通信》
- 《源码分析 — ActivityThread(一)之main()何时被调用》
- 《源码分析 — Binder机制(一)(进程间通信)》
- 《源码分析 — Binder机制(二)之IActivityManager》
二、ActivityThread.main()
方法
ActivityThread.main()
方法主要做了以下几个操作:
- 创建一个
Looper
对象,并绑定到当前线程; - 创建一个
ActivityThread
对象,并执行attach()
操作; - 获取一个
Handler
对象,用于后面发送Message
到Looper
中; - 启动
Looper
轮询器,让它从MessageQueue
中获取Message
,从而在sMainThreadHandler
中进行处理; - 抛出
RuntimeException
异常,在ZygoteInit.main()
方法中被捕获到后,关闭Socket
连接;
// ActivityThread.class
public static void main(String[] args) {
// ...代码省略...
// 1.创建一个Looper对象,并绑定到当前线程;
Looper.prepareMainLooper();
// 2.创建一个ActivityThread对象,并执行attach()操作;
ActivityThread thread = new ActivityThread();
thread.attach(false);
// 3.获取一个Handler对象,用于后面发送Message到Looper中;
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
// 4.启动Looper轮询器,让它从MessageQueue中获取Message,从而在sMainThreadHandler中进行处理;
Looper.loop();
// 5.这里抛出RuntimeException异常,会在 ZygoteInit.main()方法中被捕获到,具体请看下面一段代码;
throw new RuntimeException("Main thread loop unexpectedly exited");
}
小结:
关于第
1,3,4
涉及到Handler机制,请参考《源码分析 — Handler机制线程间通信》 ;
下面只针对第2,5
两点进行分析;
2.1 执行 ActivityThread.attach()
操作
// system =false
private void attach(boolean system) {
if (!system) {// 执行if代码块
RuntimeInit.setApplicationObject(mAppThread.asBinder());
// 获取到
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
/*
* ActivityManagerNative.getDefault()获取到的其实是ActivityManagerProxy对象,即IActivityManager接口的远程代理类;
* 这里执行的是ActivityManagerProxy.attachApplication();
* 最终通过Binder调用到ActivityManagerService.attachApplication();
*/
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
}
// ...
}
小结:
ActivityManagerNative.getDefault()
获取到的其实是IActivityManager
接口的远程代理类ActivityManagerProxy
,被代理的远程服务端是ActivityManagerService
;ActivityManagerProxy.attachApplication()
调用涉及到Binder机制
,请参考:
2.2 在 main()
最后为何要抛出 RuntimeException
异常呢?又是在哪里被捕获呢?
从《源码分析 — ActivityThread(一)之main()何时被调用》一文中,我们知道了
ActivityThread.main()
被调用的时机;
因此可以在ZygoteInit.main()
找到问题的答案;
// ZygoteInit.class
public static void main(String argv[]) {
try {
// ...
runSelectLoop(abiList);
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();//这里执行ActivityThread.main()方法
} catch (RuntimeException ex) {
//这里接收ActivityThread.main()抛出的异常,从而执行关闭Socket的操作;
closeServerSocket();
throw ex;
}
}
2.3 小结
在
ActivityThread.main()
最后一行抛出一个RuntimeException
异常,
其目的就是为了在ZygoteInit.main()
中被捕获,从而关闭Socket
通道;
其实在SystemServer.run()
的最后一行也抛出了一个RuntimeException
异常,原理相同;
三、ActivityThread、ApplicationThread、H(Handler)
之间的关系
下表是这三个类中各方法的对应关系:
ApplicationThread | H(Handler) | ActivityThread |
---|---|---|
bindApplication() | H.BIND_APPLICATION | handleBindApplication |
scheduleLaunchActivity() | H.LAUNCH_ACTIVITY | handleLaunchActivity() |
schedulePauseActivity() | H.PAUSE_ACTIVITY | handlePauseActivity() |
scheduleStopActivity() | H.STOP_ACTIVITY_HIDE | handleStopActivity() |
scheduleDestroyActivity() | H.DESTROY_ACTIVITY | handleDestroyActivity() |
scheduleRelaunchActivity() | H.RELAUNCH_ACTIVITY | handleRelaunchActivity() |
scheduleCreateService() | H.CREATE_SERVICE | handleCreateService() |
下面针对
ApplicationThread
的bindApplication()、scheduleLaunchActivity()
方法,及另两个类对应的方法进行分析;
四、类 ApplicationThread
4.1 代码分析
private class ApplicationThread extends ApplicationThreadNative {
@Override
public final void scheduleLaunchActivity(Intent intent, IBinder token, ...) {
ActivityClientRecord r = new ActivityClientRecord();
// token就是AMS的ActivityRecord中的appToken对象,用来保证每个Activity的唯一性;
r.token = token;
// ...
// 发送一个LAUNCH_ACTIVITY消息到Handler的消息队列中;
sendMessage(H.LAUNCH_ACTIVITY, r);
}
public final void bindApplication(String processName, ...) {
// ...
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
// ...
// 发送一个BIND_APPLICATION消息到Handler的消息队列中;
sendMessage(H.BIND_APPLICATION, data);
}
}
4.2 小结
- 由下面的表格可知:
IApplicationThread、IActivityManager
接口的接口服务端和接口代理类分别对应的是什么; ActivityManagerService
和应用程序不是运行在同一个进程中,所以无法和应用进程直接进行通信,而是需要借助Binder
来达到通信的目的;ApplicationThread
是运行在应用进程当中的,与ActivityThread
属于同一个进程;Binder
是单向通信的;ActivityManagerService
所在进程和应用进程间的通信:
- 应用进程访问
ActivityManagerService
所在进程:通过ApplicationThreadNative.asInterface()
获取到IActivityManager
接口的远程服务代理类ActivityManagerProxy
,从而实现通信; ActivityManagerService
所在进程访问应用进程:通过ActivityManagerNative.getDefault()
获取IApplicationThread
接口的远程服务代理类ApplicationThreadProxy
,从而实现通信;
- 应用进程访问
接口 | Client(客户端) | Service(服务端) | Proxy(远程代理类) | Proxy的获取方式 |
---|---|---|---|---|
IApplicationThread | ApplicationThreadNative | ApplicationThread | ApplicationThreadProxy | ApplicationThreadNative.asInterface() |
IActivityManager | ActivityManagerNative | ActivityManagerService | ActivityManagerProxy | ActivityManagerNative.getDefault() |
五、类 H(Handler)
5.1 代码分析
private class H extends Handler {
public static final int LAUNCH_ACTIVITY = 100;
public static final int BIND_APPLICATION = 110;
// ...
public void handleMessage(Message msg) {
switch (msg.what) {
case LAUNCH_ACTIVITY:
//...
// 执行ActivityThread.handleLaunchActivity()方法;
handleLaunchActivity(r, null);
break;
case BIND_APPLICATION:
AppBindData data = (AppBindData)msg.obj;
// 执行ActivityThread.handleBindApplication()方法;
handleBindApplication(data);
break;
}
}
}
5.2 小结
类 H
接收从 ApplicationThread
中发送出来的 Message
,然后执行 ActivityThread
中对应的方法;
六、类 ActivityThread
6.1 代码分析
public final class ActivityThread {
private void handleBindApplication(AppBindData data) {
// ...省略大段代码...
if (data.instrumentationName != null) {
// ...省略大段代码...
// 根据instrumentationName创建Instrumentation对象;
ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
// ...
} else {
// 直接创建Instrumentation对象;
mInstrumentation = new Instrumentation();
}
// 创建Application对象;
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
// 调用Application的onCreate()方法;
mInstrumentation.callApplicationOnCreate(app);
}
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
// ...
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
// ...
}
// ...
}
}
6.2 小结
ActivityThread
中存在一系列的方法,与 ApplicationThread
相对应;