由于Activity的启动涉及到的知识太多,本文不会展开太多,主要以记录启动流程为主。
Activity启动流程,我们肯定是从Activity#startActivity()着手(本文源码为26版本)。
1)Activity#startActivity()
Activity.startActivity()
=>Activity.startActivityForResult()
=>Instrumentation.execStartActivity();
2)Instrumentation#execStartActivity()
Instrumentation.execStartActivity()
=>ActivityManager.getService().startActivity()
2.1)ActivityManager.getService()
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
这里从ActivityManager中的IActivityManagerSingleton单例中获取到一个IActivityManager,IActivityManager是ServiceManager.getService(Context.ACTIVITY_SERVICE)获取到的一个远程服务通过Binder对应的代理,而这个远程服务就是ActivityManagerService(AMS),所以ActivityManager.getService().startActivity()实际是调用ActivityManagerService.startActivity()。
3)ActivityManagerService#startActivity()
Tips:从这里开始就已经是运行在ActivityManagerService进程了。
ActivityManagerService.startActivity()
=>ActivityManagerService.startActivityAsUser()
=>ActivityStarter.startActivityMayWait()
ActivityStarter是Activity的启动器,用来启动Activity,它是在ActivityManagerService的构造方法中创建,ActivityManagerService的创建之后会在《ActivityManagerService的启动流程》中说明。
4)ActivityStarter#startActivityMayWait()
ActivityStarter.startActivityMayWait()
=>ActivityStarter.startActivityLocked()
=>ActivityStarter.startActivity()
=>ActivityStarter.startActivity()(重载)
=>ActivityStarter.startActivityUnchecked()
=>ActivityStackSupervisor.resumeFocusedStackTopActivityLocked()
ActivityStackSupervisor是Activity栈的管理员,用来管理Activity栈,它是在ActivityManagerService的构造方法中创建,ActivityManagerService的创建之后会在《ActivityManagerService的启动流程》中说明。
5)ActivityStackSupervisor#resumeFocusedStackTopActivityLocked()
ActivityStackSupervisor.resumeFocusedStackTopActivityLocked()
=>ActivityStack.resumeTopActivityUncheckedLocked()
=>ActivityStack.resumeTopActivityInnerLocked()
=>ActivityStackSupervisor.startSpecificActivityLocked()
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// 获取启动的Activity对应的进程
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.getStack().setLaunchTime(r);
//如果进程已经存在
if (app != null && app.thread != null) {
//启动Activity
realStartActivityLocked(r, app, andResume, checkConfig);
return;
}
//如果进程不存在,开启新进程
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
这里暂时只看进程存在的情况,新开进程会在之后新开一篇笔记来记录。
=>ActivityStackSupervisor.realStartActivityLocked()
=>ProcessRecord.thread.scheduleLaunchActivity()
Tips:很明显我们在App启动一个Activity,这个Activity是需要运行在当前App进程的,而从step3开始启动流程就已经切到了AMS所在进程,所以最终还是需要AMS通知App进程来创建Activity,这里的ProcessRecord.thread就是一个Binder接口,它实际上就是在step3中传入的ActivityThread.mAppThread,这样AMS便持有了一个可以与ActivityThread通信的Binder对应代理。
6)ApplicationThread#scheduleLaunchActivity()
Tips:这里已经回到App进程。
ApplicationThread.scheduleLaunchActivity()
=>ActivityThread.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(ActivityThread中的Handler)中发送了一个what=H.LAUNCH_ACTIVITY的Message。
我们找到这个消息接收的地方:
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, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
}
=>ActivityThread.handleLaunchActivity()
7)ActivityThread#handleLaunchActivity()
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
//7.1
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
//7.2
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
if (!r.activity.mFinished && r.startsNotResumed) {
performPauseActivityIfNeeded(r, reason);//6.3
}
}
}
7.1)ActivityThread. performLaunchActivity()
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//7.1.1
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
//7.1.2
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback);
//7.1.3
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
//7.1.4
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
}
7.1.1)Instrumentation.newActivity()创建Activity
通过以上代码可以看到Activity是通过Instrumentation.newActivity()返回
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return (Activity)cl.loadClass(className).newInstance();
}
Tips:这里可以看出Activity实际是Instrumentation反射生成的。
7.1.2)创建Activity后,将AppContext、当前ActivityThread、Instrumentation、以及一些Activity相关信息传入。
7.1.3)Instrumentation.callActivityOnCreate()执行Activity.onCreate()
public void callActivityOnCreate(Activity activity, Bundle icicle,
PersistableBundle persistentState) {
prePerformCreate(activity);
activity.performCreate(icicle, persistentState);
postPerformCreate(activity);
}
Activity.performCreate()
final void performCreate(Bundle icicle) {
restoreHasCurrentPermissionRequest(icicle);
//**
onCreate(icicle);
//**
mActivityTransitionState.readState(icicle);
performCreateCommon();
}
可以看到到这里Activity的onCreate()就被显示的调用了
7.1.4)Activity.performStart()
Activity.performStart()
=>Instrumentation.callActivityOnStart()
=>Activity.onStart()
Activity调用onCreate()后马上调用了onStart().
7.2)ActivityThread. handleResumeActivity()
final void handleResumeActivity(IBinder token,
boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
//7.2.1
r = performResumeActivity(token, clearHide, reason);
//7.2.2
if (r != null) {
final Activity a = r.activity;
if (localLOGV) Slog.v(
TAG, "Resume " + r + " started activity: " +
a.mStartedActivity + ", hideForNow: " + r.hideForNow
+ ", finished: " + a.mFinished);
final int forwardBit = isForward ?
WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
// If the window hasn't yet been added to the window manager,
// and this guy didn't finish itself or start another activity,
// then go ahead and add the window.
boolean willBeVisible = !a.mStartedActivity;
if (!willBeVisible) {
try {
willBeVisible = ActivityManager.getService().willActivityBeVisible(
a.getActivityToken());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (r.mPreserveWindow) {
a.mWindowAdded = true;
r.mPreserveWindow = false;
// Normally the ViewRoot sets up callbacks with the Activity
// in addView->ViewRootImpl#setView. If we are instead reusing
// the decor view we have to notify the view root that the
// callbacks may have changed.
ViewRootImpl impl = decor.getViewRootImpl();
if (impl != null) {
impl.notifyChildRebuilt();
}
}
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
wm.addView(decor, l);
} else {
// The activity will get a callback for this {@link LayoutParams} change
// earlier. However, at that time the decor will not be set (this is set
// in this method), so no action will be taken. This call ensures the
// callback occurs with the decor set.
a.onWindowAttributesChanged(l);
}
}
// If the window has already been added, but during resume
// we started another activity, then don't yet make the
// window visible.
} else if (!willBeVisible) {
if (localLOGV) Slog.v(
TAG, "Launch " + r + " mStartedActivity set");
r.hideForNow = true;
}
// Get rid of anything left hanging around.
cleanUpPendingRemoveWindows(r, false /* force */);
// The window is now visible if it has been added, we are not
// simply finishing, and we are not starting another activity.
if (!r.activity.mFinished && willBeVisible
&& r.activity.mDecor != null && !r.hideForNow) {
if (r.newConfig != null) {
performConfigurationChangedForActivity(r, r.newConfig);
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
+ r.activityInfo.name + " with newConfig " + r.activity.mCurrentConfig);
r.newConfig = null;
}
if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
+ isForward);
WindowManager.LayoutParams l = r.window.getAttributes();
if ((l.softInputMode
& WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
!= forwardBit) {
l.softInputMode = (l.softInputMode
& (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
| forwardBit;
if (r.activity.mVisibleFromClient) {
ViewManager wm = a.getWindowManager();
View decor = r.window.getDecorView();
wm.updateViewLayout(decor, l);
}
}
r.activity.mVisibleFromServer = true;
mNumVisibleActivities++;
if (r.activity.mVisibleFromClient) {
r.activity.makeVisible();
}
}
if (!r.onlyLocalRequest) {
r.nextIdle = mNewActivities;
mNewActivities = r;
if (localLOGV) Slog.v(
TAG, "Scheduling idle handler for " + r);
Looper.myQueue().addIdleHandler(new Idler());
}
r.onlyLocalRequest = false;
// Tell the activity manager we have resumed.
if (reallyResume) {
try {
ActivityManager.getService().activityResumed(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}
}
7.2.1)ActivityThread.performResumeActivity()
ActivityThread.performResumeActivity()
=>Activity.performResume()
=>Instrumentation.callActivityOnResume()
=>Activity.onResume()
这里完成了Activity.onResume()的显示调用
7.2.2)到这里才真正的开始绘制页面,将页面布局添加到window的DecorView。
总结:
Activity在用户进程启动时,通过Binder机制获取到AMS的代理,然后调用AMS的startActivity(),AMS中ActivityStarter、ActivityStackSupervisor、ActivityStack共同完成启动activity的系统工作,之后通过传入的ApplicationThread代理通知到ActivityThread,回到用户进程,通过Instrumentation完成Activity的创建,以及各个启动声明周期的回调。
这里有2个细节可以留意一下:
1.Activity是在Instrumentation中反射生成的;
2.Activity是在回调完onResume()后才开始绘制页面的。