android源码解析之(十一)--)应用进程启动流程
在android guide中有这样的一段关于android应用程序进程的描述:
By default, every application runs in its own Linux process. Android starts the process when any of the application's components need to be executed, then shuts down the process when it's no longer needed or when the system must recover memory for other applications.
每一个android应用默认都是在他自己的linux进程中运行。android操作系统会在这个android应用中的组件需要被执行的时候启动这个应用进程,并且会在这个应用进程没有任何组件执行或者是系统需要为其他应用申请更多内存的时候杀死这个应用进程。所以当我们需要启动这个应用的四大组件之一的时候如果这个应用的进程还没有启动,那么就会先启动这个应用程序进程。
本节主要是通过分析Activity的启动过程介绍应用程序进程的启动流程。
在上一篇文章中我们简要的介绍了Launcher的启动流程,在SystemServer进程执行完成,各种系统服务启动完成之后,会调用ActivityManagerService中的systemReady()方法,在systemReady()方法中会执行Launcher启动的相关逻辑了,
Launcher应用程序在启动过程中会通过PackageManagerService服务请求查询系统所有的已安装应用的包名,图标和应用名称等信息,然后填充到Launcher中的Adapter中,这样点击某一项应用图标的时候就可以根据该图标的包名和启动Activity的类名初始化Intent对象,然后调用startActivity(Intent)启动相关的应用程序了。
其实android中应用进程可以通过许多方式启动,比如启动一个Activity,启动一个Service,启动一个ContentProvider或者是一个BroadcastReceiver,也就是说我们可以通过启动四大组件的方式启动应用进程,在应用进程没有启动的时候,如果我们通过启动这些组件,这时候系统会判断当前这些组件所需要的应用进程是否已经启动,若没有的话,则会启动应用进程。
这里我们通过Launcher简单分析一下应用进程的启动流程。通过上一篇Launcher启动流程,我们知道每一个launcher中的图标对应着一个应用报名和启动activity类名,查看LauncherActivity中的图标点击事件:
protected void onListItemClick(ListView l, View v, int position, long id) {
Intent intent = intentForPosition(position);
startActivity(intent);
}
在通过应用包名和启动activity类名构造完成Intent之后,我们调用了startActivity方法来启动这个activity,很明显的,当前这个应用并没有启动,也就是说我们调用的startActivity方法不单单为我们启动了这个activity也同时在启动activity之前启动了这个应用进程,好了,那我们这里就以这个方法为入口分析一下应用进程的启动流程。
跟踪代码到Activity,发现其调用了startActivity的重载方法:
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
继续跟进:
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
很明显的我们此时传递的options为空:
public void startActivityForResult(Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
好吧,最后调用的还是这个重载方法:
= 0) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}" data-snippet-id="ext.a4d05821523ca3cace9fa20a2ea364f3" data-snippet-saved="false" data-codota-status="done">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);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
可以发现这里调用了mInstrumentation.execStartActivity方法,这里先简单介绍一下Instrumentation对象,他是Android系统中应用程序端操作Activity的具体操作类,这里的操作段是相对于ActivityManagerService服务端来说的。也就是说当我们在执行对Activity的具体操作时,比如回调生命周期的各个方法都是借助于Instrumentation类来实现的。
好了,下面我们继续看一下Instrumentation的execStartActivity方法:
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess();
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);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
这里主要关注这个代码:
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
这断代码实际上是进程间通讯,我们可以发现ActivityManagerNative继承于Binder接口,所以ActivityManagerNative就是一个Binder对象,然后上面一节我们介绍SystemServer进程的时候对ActivityManagerService有过了解,发现其继承于ActivityManagerNative,好吧,了解过Binder机制的童鞋就知道了,ActivityManagerService就是这个Binder机制的服务器端而ActivityManagerNative就是这个Binder机制的客户端,所以我们这里调用的startActivity实际上是讲参数传递给ActivityManagerService并执行ActivityManagerService的startActivity方法。
既然这样,我们看一下ActivityManagerService的startActivity方法:
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, S