本文的合集已经编著成书,高级Android开发强化实战,欢迎各位读友的建议和指导。在京东即可购买:https://item.jd.com/12385680.html
本文是探索Activity启动源码的第二篇, 其余参考第一篇.
第一篇的流程图:
第一篇已经探索至关键位置, 即ActivityStackSupervisor的realStartActivityLocked方法, 方法如其名, 从此开始, 才是真正地(Real)启动(Start). Let's start!
ActivityManagerService
ActivityStackSupervisor#realStartActivityLocked:
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
// 当屏幕方向修改时, 推迟恢复, 防止冗余启动Activity.
if (checkConfig) {
Configuration config = mWindowManager.updateOrientationFromAppTokens(
mService.mConfiguration,
r.mayFreezeScreenLocked(app) ? r.appToken : null);
mService.updateConfigurationLocked(config, r, false, true /* deferResume */);
}
// 将进程描述符(ProcessRecord)设置入Activity描述符(ActivityRecord)
r.app = app;
app.waitingToKill = null; // 避免在后台被杀死
r.launchCount++; // 增加启动次数
r.lastLaunchTime = SystemClock.uptimeMillis(); // 最新启动时间
// 当Activity描述符不在进程的Activity列表中, 将Activity添加入进程的Activity列表
int idx = app.activities.indexOf(r);
if (idx < 0) {
app.activities.add(r);
}
// AMS更新进程描述符为最少最新使用(LRU).
mService.updateLruProcessLocked(app, true, null);
// ...
try {
// ...
// 远程调用ApplicationThread的scheduleLaunchActivity
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
// ...
} catch (RemoteException e) {
// ...
}
// ...
return true;
}
ActivityRecord即Activity描述符(变量r), 含有被启动的Activity信息; ProcessRecord即进程描述符(变量app), 含有当前应用的进程信息.
app.thread类型是IApplicationThread, 通过IApplicationThread的代理ApplicationThreadProxy, 远程调用ApplicationThread的scheduleLaunchActivity方法, ApplicationThread是IApplicationThread的最终实现.
启动Activity再次由AMS(ActivityManagerService)通过远程调用(Binder)交给应用进程(ActivityThread)处理. ApplicationThread是ActivityThread的私有类.
ApplicationThread#scheduleLaunchActivity:
@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<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
// ...
// 即来自客户端(AMS)的Activity描述符
ActivityClientRecord r = new ActivityClientRecord();
// 将AMS的Activity描述符, 转换为当前进程的Activity描述符
r.token = token;
// ...
// 封装, 发送启动消息给H类处理, 并传递Activity描述符
sendMessage(H.LAUNCH_ACTIVITY, r);
}
sendMessage是重载方法, 最终调用H类处理数据.
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
// ...
// 最终由H类(Handler)处理数据
mH.sendMessage(msg);
}
将启动Activity交给ActivityThread的Handler H类处理.
private class H extends Handler {
public void handleMessage(Message msg) {
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
ActivityClientRecord r = (ActivityClientRecord)msg.obj;
// 设置Activity描述符的包信息
r.packageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo, r.compatInfo);
// 至此, 完成启动Activity已经由AMS交给当前应用, 在当前应用中启动Activity.
handleLaunchActivity(r, null);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
}
}
}
启动Activity, 先由当前进程, 通过ActivityManagerNative#getDefault#startActivity方法, 交给AMS处理, AMS管理Activity的Stack和Task, 并设置Activity描述符(Record); 再通过app.thread#scheduleLaunchActivity方法, 继续交给当前进程处理.
AMS切换当前线程的流程图:
ActivityThread
ActivityThread#handleLaunchActivity:
handleLaunchActivity调用performLaunchActivity方法, 继续执行启动, 在成功后, 调用handleResumeActivity方法, 执行显示Activity.
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
// 因为当前进程正在活跃, 所以跳过在后台中执行GC.
unscheduleGcIdler();
// ...
// 确保使用最近的环境配置
handleConfigurationChanged(null, null);
if (localLOGV) Slog.v(
TAG, "Handling launch of " + r);
// 在创建Activity前, 初始化WindowManagerGlobal, 即WindowManagerService
WindowManagerGlobal.initialize();
// 执行启动Activity
Activity a = performLaunchActivity(r, customIntent);
// 在启动成功后, 处理恢复Activity
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
Bundle oldState = r.state;
// 恢复Activity
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
// ...
}
} else {
// 如果发生错误, 则AMS停止启动Activity
try {
ActivityManagerNative.getDefault()
.finishActivity(r.token, Activity.RESULT_CANCELED, null,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}
ActivityThread#performLaunchActivity:
performLaunchActivity方法是Activity启动的核心:
- 获取Activity的组件信息(ComponentName);
- 根据组件使用反射创建Activity(newActivity);
- 将Activity绑定(attach)Application和BaseContext;
- 相继调用onCreate, onStart, onRestoreInstanceState, onPostCreate等方法.
- 放入Activity列表(Map)中统一管理, token是key.
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
// 通过应用信息, 兼容信息, 从PMS, 获取Activity的包信息
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
// 获取组件信息
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
// 当指定Activity时, 使用包名和类名创建组件
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
// 通过反射, 使用ClassLoader创建Activity
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
// ...
} catch (Exception e) {
// ...
}
try {
// 使用单例模式, 创建Application
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
// ...
if (activity != null) {
// 创建Activity的上下文BaseContext
Context appContext = createBaseContextForActivity(r, activity);
// ...
// 将Activity绑定上下文appContext, 和应用app
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);
// ...
// 设置主题
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false; // 判断执行是否成功, 成功会置true
// 调用Activity的onCreate方法.
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
// ...
// 调用Activity的onStart方法.
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
// 调用Activity的onRestoreInstanceState方法.
if (!r.activity.mFinished) {
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
// 调用Activity的onPostCreate方法.
if (!r.activity.mFinished) {
activity.mCalled = false; // 判断执行是否成功, 成功会置true
if (r.isPersistable()) {
mInstrumentation.callActivityOnPostCreate(activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnPostCreate(activity, r.state);
}
// ...
}
}
r.paused = true;
// 将Activity放入ActivityThread的Activity数组中统一管理.
mActivities.put(r.token, r);
} // ...
return activity;
}
onPostCreate: Called when activity start-up is complete (after onStart() and onRestoreInstanceState(Bundle) have been called). Applications will generally not implement this method; it is intended for system classes to do final initialization after application code has run.
在调用时, 表明Activity已经完全启动, 只剩下显示(onResume).
通过分析performLaunchActivity, 我们也更加清晰Activity的生命周期, 顺序如下, onCreate, onStart, onRestoreInstanceState, onPostCreate. 注意, onStart是Activity处理; 其余三个是Instrumentation处理, 支持继承重写相应方法, 自行处理.
至此, Activity已经完全启动, 并调用相应的生命周期方法.
OK, that's all! Enjoy it!