Activity 启动调用流程 (基于5.0源码)
我们从 startActivity 开始:
startActivity()
startActivity()方法有多个重载,但是都会调用到 startActivityResult:
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
if (mParent == null) {
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
... //
}
...// 省略大量代码
}
Ok,我们可以看到 调用到了 Instrumentation 的 execStartActivity 方法。
下面我们看一下 execStartActivity
中的两行重点代码:
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
可以看到,调用到了 ActivityManagerNative.getDefault() 的 startActivity。 而getDefault()返回的是一个 IActivityManager.
checkStartActivityResult()是校验activity 的启动结果的,比如我们没有在androidManifest 注册,等等。就会抛出异常。
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
可以看到是一个单例。IActivityManager 是一个 Binder 接口
public interface IActivityManager extends IInterface {
...// 方法
}
而该Binder 的真正实现 是 ActivityManagerService(简称 AMS) 。 所以接下来我们来看 AMS 中的 startActivity实现
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, options,
UserHandle.getCallingUserId());
}
啥实事也没干,直接转调了 startActivityAsUser
继续跟进,
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
enforceNotIsolatedCaller("startActivity");
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
false, ALLOW_FULL_ONLY, "startActivity", null);
// TODO: Switch to user app stacks here.
return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, options, userId, null, null);
}
该方法调了 ActivityStackSupervisor
的 startActivityMayWait
方法。 在该方法中又调用了自身的 startActivityLocked
方法,该方法中又调用到 startActivityUncheckedLocked() 又从该方法调用到了 ActivityStack 的 resumeTopActivityLocked
方法。这时 已经从 ActivityStackSupervisor 转到了 ActivityStack
final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
if (inResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean result = false;
try {
// Protect against recursion.
inResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, options);
} finally {
inResumeTopActivity = false;
}
return result;
}
上面代码看到 resumeTopActivityLocked
调用了 resumeTopActivityInnerLocked
在该方法中:
mStackSupervisor.startSpecificActivityLocked(next, true, false);
又回到了 ActivityStackSupervisor
中, ok, startSpecificActivityLocked
中 调用了 realStartActivityLocked
看到这个名字,说明我们已经差不多了。 该方法的关键代码如下:
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
r.compat, r.task.voiceInteractor, app.repProcState, r.icicle, r.persistentState,
results, newIntents, !andResume, mService.isNextTransitionForward(),
profilerInfo);
那么app.thread 是什么呢?? 它是 IApplicationThread
类型。
public interface IApplicationThread extends IInterface {}
是一个Binder 接口。 AMS进程通过该 binder接口 来调用 app进程的方法。
IApplicationThread
的实现 是在 ActivityThread 中的 ApplicationThread
, IApplicationThread 中定义了很多接口方法。都是和四大组件相关的
void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving,
int configChanges, boolean dontReport) throws RemoteException;
void scheduleStopActivity(IBinder token, boolean showWindow,
int configChanges) throws RemoteException;
void scheduleWindowVisibility(IBinder token, boolean showWindow) throws RemoteException;
void scheduleSleeping(IBinder token, boolean sleeping) throws RemoteException;
void scheduleResumeActivity(IBinder token, int procState, boolean isForward, Bundle resumeArgs)
throws RemoteException;
void scheduleSendResult(IBinder token, List<ResultInfo> results) throws RemoteException;
void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
IVoiceInteractor voiceInteractor, int procState, Bundle state,
PersistableBundle persistentState, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
ProfilerInfo profilerInfo) throws RemoteException;
void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, int configChanges,
boolean notResumed, Configuration config) throws RemoteException;
void scheduleNewIntent(List<Intent> intent, IBinder token) throws RemoteException;
......
ok 我们来看 ApplicationThread
的实现.
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
IVoiceInteractor voiceInteractor, int procState, Bundle state,
PersistableBundle persistentState, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
ProfilerInfo profilerInfo) {
updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.voiceInteractor = voiceInteractor;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.persistentState = persistentState;
r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;
r.startsNotResumed = notResumed;
r.isForward = isForward;
r.profilerInfo = profilerInfo;
updatePendingConfiguration(curConfig);
sendMessage(H.LAUNCH_ACTIVITY, r);
}
scheduleLaunchActivity
中保存了启动Activity的相关信息,然后 发送了一个消息 H.LAUNCH_ACTIVITY
这里呢,我们就需要提一下这个 H .
final H mH = new H();
H 继承自Handler。负责系统消息的处理。 消息的处理是在 handleMessage
方法中。 至于这里为什么要使用Handler 。 因为之前的操作 都是在服务端的 Binder 线程池中,所以我们这里需要切换到主线程。 handleMessage中的 调用了 handleLaunchActivity
方法。 而该方法 又调用了 performLaunchActivity
方法.
该方法中做了如下几件事:
1.从ActivityClientRecord 中取出 待启动的Activity 的组件信息。
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
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);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
2.通过Instrumentation 的 newActivity 方法 使用类加载器创建 Activity 对象
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.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);
}
}
3.通过LoadedApk 的 makeApplication 方法来尝试创建 Application对象。
4.创建ContextImpl 对象并通过Activity 的 attach 方法来完成一些重要数据的初始化
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.voiceInteractor);
ContextImpl 是context 的具体实现,Context 中的大部分逻辑都是由 ContextImpl 来实现的。 ContextImpl 是通过 Activity 的 attach 方法 来和 Activity 建立关联的。 而且 attach 方法中 还会完成 Window 的创建 并建立和 Winwod 的关联。 这样当Window 接收到外部输入事件后就可以传递给Activity 了。
5.调用Activity 的 OnCreate 方法。
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
整体总结:
当启动一个Activity时,会通过 Instrumentation 类来 execStartActivity来启动,该类 可以看作是一个管家。里面有很多 关于 Activity 生命周期的方法,可以看作是一个中间件。 在该方法中会 调用 IActivityManager 中的 startActivity 。该接口是个Binder接口,真正的实现是 服务端的 AMS, 在ams 中会 涉及到两个类 ActivityStackSupervisor 和 ActivityStack 处理 Activity 相关的启动逻辑。 当准备好后, 会调用 app.thread.scheduleLaunchActivity(). app.thread 的类型是 IApplicationThread 接口,是个Binder 接口。真正的实现类是 ApplicationThread 。 在 scheduleLaunchActivity
中进行了数据的存储,然后发送 LAUNCH_ACTIVITY 的消息,由 H 。 H 继承自Handler。 此处由于AMS 端的调用是在 binder 线程池,所以要切换到主线程。 在 handleMessage 中进行了相关的 Activity的创建、初始化、以及 OnCreate 的调用。
简记:
Handler 在Android 中线程通讯起着很大的作用, Framework 层有很多的Handler,运行在不同的线程; 而我们应用层也有一个比较重要的Handler,即 ActivityThread
中的 mH. 运行在 ui 线程。
ApplicationThread
为 IApplicationThread 的具体实现类, 用来接收服务端的消息, 四大组件就是通过 ApplicationThread
来接收服务端的消息的。
ActivityStarter 处理一些 intent 和 flag 。 然后交给ActivityStackSupervisor 和 ActivityStack 来处理被调用Activity 的进程进栈。 如果被调用者的进程存在,就会使用 ApplicationThread 这个客户端的 Binder 通知已存在的调用者进程启动Activity, 如果不存在,就会使用 Socket 通知 Zygote 进程 fork 出一个进程,用来承载即将启动的Activity。
ActivityStarter : intent 和 flag 如何打开Activity
ActivityStack: 管理Activity
ActivityStack 管理Activity的方法:
startActivityLocked()
resumeTopActivityLocked()
completeResumeLocked()
startPausingLocked()
completePauseLocked()
stopActivityLocked()
activityPausedLocked()
finishActivityLocked()
activityDestroyedLocked()