文章目录
一、Activity的启动过程?
Acivity的工作过程,在显示调用的情形下,只需要通过如下代码即可完成:Intent intent=new Intent(this,TestActivity.class);
startActivity(intent);
startActivity方法存在多种重载方式,但最终都会调用到startActivityForResult方法,其具体实现如下所示。
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
//一般的Activity的mParent为null
if (mParent == null) {
//调用Instrumentation.execStartActivity()启动新的Activity。mMainThread类型为ActivityThread, 在attach()函数被回调时被赋值。
Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);
if (ar != null) { // 如果activity之前已经启动,而且处于阻塞状态,execStartActivity函数直接返回要启动的activity的result或者null。(注意:这就是Activity.onActivityResult()会在启动另外一个activity启动时被回调的原因。
// 若result非空,发送结果给本activity,即onActivityResult会被调用。
mMainThread.sendActivityResult(mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
// 如果这次启动需要被启动的activity返回一个结果,则在收到返回结果前,本activity保持不可见。
mStartedActivity = true;
}
final View decor = mWindow != null ? mWindow.peekDecorView() : null;
if (decor != null) {
decor.cancelPendingInputEvents();
}
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
//在ActivityGroup内部的Activity调用startActivity的时候会走到这里,内部处理逻辑和上面是类似的
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
方法里面主要关注 Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options)执行语句,查看execStartActivity方法内部执行逻辑。
根据方法参数的类型可知mMainThread.getApplicationThread()返回ActivityThread对象即IBinder对象
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
//将contextThread转成ApplicationThread.
IApplicationThread whoThread = (IApplicationThread) contextThread;
if (mActivityMonitors != null) {
synchronized (mSync) {
//检查是否存在这个activity
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
if (am.match(who, null, intent)) {
am.mHits++;
if (am.isBlocking()) { //若找到,而且处于阻塞状态,直接返回。
return requestCode >= 0 ? am.getResult() : null;
}
break;
}
}
}
}
try {
intent.migrateExtraStreamToClipData(); //转移数据
intent.prepareToLeaveProcess(); //准备让intent离开一个app进程
//通过AcitivityManagerNative与ActivityManagerService关联起来,两个类的关系如下图,由ActivityManagerService去执行实际动作。
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, null, options);
//检查启动结果,如果无法打开activity,则抛出诸如ActivityNotFoundException类似的各种异常
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
return null;
}
函数里面主要通过 ActivityManagerNative.getDefault().startActivity()方法完成Activity的启动。ActivityManagerNative继承自Binder并实现了IActivityManager这个Binder接口,ActivityManagerNative.getDefault()方法如下所示
static public IActivityManager getDefault() {
return gDefault.get();
}
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;
}
};
ActivityManagerNative.getDefault()方法返回的其实是一个IActivityManager类型的Binder对象,它的具体实现类是ActivityManagerService,且ActivityManagerService也是一个Binder对象。其ActivityManagerService(AMS)这个对象采用单列模式对外提供,Singleton是一个单列的封装类,在第一次调用它的get方法时会通过creat方法初始化AMS这个Binder对象,在后续的调用中则直接返回之前创建的对象。
根据上面的分析可知 ActivityManagerNative.getDefault().startActivity()方法实际上是调用了AMS.startActivity()方法。AMS.startActivity()代码如下
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags,
String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
}
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags,
String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
enforceNotIsolatedCaller("startActivity");
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
false, true, "startActivity", null);
// TODO: Switch to user app stacks here.
return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
null, null, options, userId);
}
其主要执行逻辑为调用mStackSupervisor.startActivityMayWait()方法,类ActivityStackSupervisor是用来辅助ActivityManagerService对Activity和Task的管理的。调用mStackSupervisor.startActivityMayWait()函数后,会执行下面几个函数,调用关系参照时序图,函数里涉及很多细节,这里只简单描述下它们的主要功能:
- ActivityStackSupervisor.startActivityLocked(): 检查启动权限,创建新的ActivityRecord。
- ActivityStackSupervisor.startActivityUncheckedLocked():处理intent携带的launch flags, launchMode。
- ActivityStack.startActivityLocked():将activity放到所属task的顶部,重置Task(resetTaskIfNeededLocked),调用WindowManager.setAppStartingWindow()。
- ActivityStackSupervisor.resumeTopActivitiesLocked():判断ActivityStack数组中是否存在target ActivityStack。
- ActivityStack.resumeTopActivityLocked(): 从当前activity切换到要启动的activity。
- ActivityStackSupervisor.startSpecificActivityLocked():获取ProcessRecord(若要启动的activity的应用已经在运行),若获取ProcessRecord存在则调用realStartActivityLocked(),否则调用 ActivityManagerServices.startProcessLocked()创建新的ProcessRecord,最后调用Process.start()启动新的进程(最终调用Zygote启动新的进程,为了避免混淆,这部分在时序图中没有体现,后面再研究)。
- ActivityStackSupervisor.realStartActivityLocked(): 调用mWindowManager.setAppVisibility()设置app可见。
- ActivityThread.scheduleLauncherActivity(): 发送Message LAUNCH_ACTIVITY给Handler.
Handler接收到message后,执行ActivityThread.handleLaunchActivity()方法
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
Activity a = performLaunchActivity(r, customIntent); // 返回一个activity.
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed);
if (!r.activity.mFinished && r.startsNotResumed) {
// 当这个activity没有finished而且没有处于resumed状态时,Acivity Manager实际上想要这个activity以paused状态开始,因为它需要可见,但是又不在前台。 // 为此,需要经过正常启动(因为activity希望在它们的window被显示前,它们第一次运行时通过onResume),然后暂停它。The activity manager actually wants this one to start out
//然而,在这种情况下,不需要走完整的暂停周期(比如freezing等),因为activity假定它可以刚好保留它当前的所有状态。
try {
r.activity.mCalled = false;
mInstrumentation.callActivityOnPause(r.activity);
......
} catch (SuperNotCalledException e) {
......
} catch (Exception e) {
......
}
r.paused = true;
}
} else {
......
}
}
performLaunchActivity方法最终完成了Activity对象的创建和启动过程。
performLaunchActivity()这个方法做了几件重要的事情:创建activity实例,调用Activity.attach()设置参数,触发Activity.onCreate()。
1.从ActivityClientRecord中获取待启动的Activity的组件信息
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) { // 填充package info
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); //设置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); // 根据Activity的类名,通过Java反射机制创建对应的Activity.
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
......
}
3.通过LoadedApk的makeApplication方法来尝试创建Application对象,且一个应用只有一个Application对象。
4.创建ContextImpl对象并通过Activity的attach方法来完成一些重要的数据的初始化,ContextImpl是一个很重要的数据结构,它是Context的具体实现,Context中大部分逻辑是由ContextImpl来完成的。ContextImpl是通过Activity的attch方法来和Activity建立关联的,除此之外,在attach方法中activity还会完成window的创建并建立自己和window的关联,这样当window接收外部输入事件后就可以将事件传递给Activity
5.调用Activity的onCreat方法
由于Activity的onCreat()已经被调用,这就意味着Activity已经完成了整个启动过程。