// 省略部分代码
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
// 省略后续代码
}
}
}
在attach方法中,调用ActivityManager.getService()
方法,获取到远程的IActivityManager
对象,并将一个ApplicationThread
实例传入。
ApplicationThread继承至IApplicationThread.Stub
,即Binder进程间通信的本地实现类。它有很多与Activity生命周期相关的方法,大都以scheduleXXX
命名:
至此,我们可以总结一下:
ActivityThread
的main
方法,是应用程序启动的入口。- Activity生命周期是由系统底层控制,通过
Binder
机制,回调到ApplicationThread
的scheduleXXX
方法中。 ActivityThread
和ApplicationThread
针对每个应用,都只有一个实例。
这里有个疑问:
为什么没有
scheduleStartActivity
方法?难道Activity的onStart()
生命周期回调,不是由ActivityManager
发送消息控制的?
带着这个疑问,我们开始阅读这些scheduleXXX方法的源码。
二、Activity生命周期
我们从ApplicationThread中的scheduleLaunchActivity
方法开始分析,因为由名字可以猜测它应该会执行Activity创建和启动工作。
public final class ActivityThread {
// 省略部分代码
private class ApplicationThread extends IApplicationThread.Stub {
// 省略部分代码
@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();
// 给ActivityClientRecord赋值
updatePendingConfiguration(curConfig);
sendMessage(H.LAUNCH_ACTIVITY, r);
}
// 省略部分代码
}
}
在scheduleLaunchActivity方法中,首先创建了一个ActivityClientRecord
对象,并对其进行赋值。
ActivityClientRecord:用于记录与Activity相关的数据。
然后通过Handler,将线程由Binder线程
切换到主线程
。最终调用到ActivityThread的handleLaunchActivity
方法。
public final class ActivityThread {
// 省略部分代码
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
// 省略部分代码
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
// 省略部分代码
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
if (!r.activity.mFinished && r.startsNotResumed) {
// The activity manager actually wants this one to start out paused, because it
// needs to be visible but isn’t in the foreground. We accomplish this by going
// through the normal startup (because activitie