1.前言
在前面Activity启动过程及界面绘制流程解析开篇和Android 异步消息处理机制两篇文章中详细介绍了Activity启动过程中常用的两个知识点,binder机制以及android异步消息机制。在有了这个基础之后,我们终于可以进入activity启动流程的学习了。
2.Activity启动相关进程介绍
-
zygote进程
zygote从字面上来说是受精卵的意思,用来孵化后代。在android源码中也确实是这个作用,zygote进程是java层所有程序进程的父进程,它是android空间程序的孵化器,android空间所有程序都是由zygote进程启动的,我们平时自己写的应用程序进程当然也是由zygote孵化,后面会有介绍。 -
system_server进程
system_server进程是binder service所在的进程,该进程里面运行了很多binder service。例如下文要涉及到的ActivityManagerService及平常经常用到的WindowManagerService和PackageManagerService等binder服务。 -
应用程序进程
应用程序进程通常就是我们开发中应用所在的进程。activity实例运行在这个进程。
3.Activity启动具体流程
通常我们启动一个activity是通过Activity的startActivity方法,如下:
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
直接调用Activity的两个参数的startActivity方法:
//options这个参数,Activity这个方法的注释是怎样启动activity,不去讨论
//平时调用的时候options为空
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);
}
}
不管两个参数还是三个参数的startActivityForResult方法都会调到activity的3个参数的startActivityForResult方法中,下面来看3个参数的startActivityForResult方法。
//requestCode启动activity是否需要返回值,默认为-1,不需要返回值
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
if (mParent == null) {
//通过Instrumentation的execStartActivity来启动activity
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
......
} else {
......
}
在startActivityForResult中调用了Instrumentation的execStartActivity方法来继续下一个步骤。Instrumentation从字面上来看是仪器的意思,具体到程序中是管理activity的一个工具类,activity的生命周期方法都是由Instrumentation这个仪器来控制,一个进程中只用一个Instrumentation实例。再来看Instrumentation的execStartActivity方法:
/**
* Execute a startActivity call made by the application. The default
* implementation takes care of updating any active {@link ActivityMonitor}
* objects and dispatches this call to the system activity manager; you can
* override this to watch for the application to start an activity, and
* modify what happens when it does.
* @param who The Context from which the activity is being started.
* @param contextThread The main thread of the Context from which the activity
* is being started.
* @param token Internal token identifying to the system who is starting
* the activity; may be null.
* @param target Which activity is performing the start (and thus receiving
* any result); may be null if this call is not being made
* from an activity.
* @param intent The actual Intent to start.
* @param requestCode Identifier for this request's result; less than zero
* if the caller is not expecting a result.
* @param options Addition options.
*
* @return To force the return of a particular result, return an
* ActivityResult object containing the desired data; otherwise
* return null. The default implementation always returns null.
*/
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
......
try {
......
//在此通过binder完成跨进程间的调用
//通过ActivityManagerService来实现activity的启动
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;
}
这个方法中有几个参数需要特别注意:第一个参数通常代表原始的activity(通过A activity 启动B activity,则A是原始activity,B是目标activity)第二个参数是一个IBinder类型的ApplicationThread,提到IBinder,自然猜测ApplicationThread是一个Binder类,下面来验证。
先看activity的startActivityForResult方法:
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
if (mParent == null) {
Instrumentation.ActivityResult ar =
//第二个参数通过mMainThread.getApplicationThread()
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
......
} else {
......
}
在代码中的注释处,我们看到ApplicationThread类型的参数是通过mMainThread.getApplicationThread()方法得到的,mMainThread在这里是ActivityThread类型的变量。下面来瞅一样ActivityThread的getApplicationThread方法:
public ApplicationThread getApplicationThread()
{
return mAppThread;
}
简单的返回一个mAppThread变量,而:
final ApplicationThread mAppThread = new ApplicationThread();
所以execStartActivity第二个参数实际上是一个ApplicationThread对象,
而:
private class ApplicationThread extends ApplicationThreadNative {
......
public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
sendMessage(
finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
token,
(userLeaving ? 1 : 0) | (dontReport ? 2 : 0),
configChanges);
}
......
}
从代码中可以看出ApplicationThread又是继承ApplicationThreadNative的:
public abstract class ApplicationThreadNative extends Binder
implements IApplicationThread {
......
}
从这里就可以看出来ApplicationThread的确是一个binder对象。
再回到Instrumentation的execStartActivity方法的参数中,后面的几个参数就不再分析了,execStartActivity方法注释上写得比较清楚了。我们再来看这个方法的实现:
try {
......
//在此通过binder完成跨进程间的调用
//通过ActivityManagerService来实现activity的启动
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);
}
先来看下ActivityManagerNative.getDefault()方法:
public abstract class ActivityManagerNative extends Binder implements IActivityManager{
......
static public IActivityManager getDefault() {
return gDefault.get();
}
......
}
看到这里,再次猜测gDefault.get()得到的IActivityManager的对象实际上是一个binder的代理对象。我们来验证一下想法是否正确。
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
//1.通过ServiceManager得到IActivityManager类型的binder对象
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
//2.通过IActivityManager类型的binder对象得到IActivityManager的代理对象
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
gDefault是一个Singleton类型的对象,Singleton是一个实现单例模式的工具类,通过Singleton的get方法能得到create方法的返回值,也就是说gDefault.get()方法能得到一个IActivityManager类型的对象。这个IActivityManager对象到底是什么呢?先看上述代码的注释一处:
在Activity启动过程及界面绘制流程解析开篇这篇文章中曾经提到过ServiceManager,ServiceManager是binder service的管理类,负责管理运行的binder service,提供客户端访问binder service的接口。这里得到了体现,应用进程通过ServiceManager得到了binder service在内核驱动中的对象,然后通过注释二处转化为客户端使用的binder代理对象,从而调用binder service的方法。这样就验证了ActivityManagerNative.getDefault()是一个binder代理对象,也实现了与binder service建立连接,可以调用binder service的方法。这个binder service实际上是上文曾经提到过的system_server进程中的ActivityManagerService。
ActivityManagerService实际上最终管理activity生命周期的地方,上文曾经提到过的Instrumentation也可以管理activity生命周期。那么他们有什么不同呢?Instrumentation管理activity实际上也需要听从ActivityManagerService的命令。ActivityManagerService通过ApplicationThread将命令传达给Instrumentation,Instrumentation具体调用activity的生命周期方法。除此之外,ActivityManagerService还能管理其他四大组件,所以ActivityManagerService这个binder service在android框架中占有举足轻重的地位。
粗略说明了ActivityManagerService作用之后,我们再接着分析与activity启动相关的方法。
在Instrumentation的execStartActivity方法中还有一点需要特别注意。在android建立binder连接有两种方式,一种是通过ServiceManager,如应用程序访问ActivityManagerService。还有一种是通过已经建立好的binder连接来建另一个binder连接,如Instrumentation的execStartActivity方法中的ActivityManagerNative.getDefault() .startActivity中会将ApplicationThread类型whoThread传到ActivityManagerService中,然后ActivityManagerService通过ApplicationThread来控制应用程序。
进入ystem_server进程调用ActivityManagerService的startActivity方法:
@Override
public int startActivity(IBinder whoThread, String callingPackage,
Intent intent, String resolvedType, Bundle options) {
......
IApplicationThread appThread;
......
appThread = ApplicationThreadNative.asInterface(whoThread);
......
return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
resolvedType, null, null, null, null, 0, 0, null, null,
null, options, callingUser, null, tr);
}
将应用程序传过来的ApplicationThread转换成binder代理对象,以便ActivityManagerService通过这个代理对象控制应用程序。然后调用ActivityStackSupervisor的startActivityMayWait继续下一步操作。在分析下一步操作之前,我们先了解下下面这几个类的作用:
- ActivityStack:Activity在ActivityManagerService的栈管理,用来记录已经启动的Activity的先后关系,状态信息等。通过ActivityStack决定是否需要启动新的进程。
- ActivityRecord:应用程序每次启动一个Actvity会有一个对应的ActivityRecord对象,记录Activity的状态以及其他的管理信息。
- TaskRecord:Task记录信息,一个Task可能有多个ActivityRecord,但是一个ActivityRecord只能属于一个TaskRecord,与activity启动模式相关。
有了这个基础之后再接着分析:
final int startActivityMayWait(IApplicationThread caller, int callingUid,
String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, String profileFile,
ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
Bundle options, int userId) {
int res = startActivityLocked(caller, intent, resolvedType,
aInfo, resultTo, resultWho, requestCode, callingPid, callingUid,
callingPackage, startFlags, options, componentSpecified, null);
}
继续调用ActivityStackSupervisor的startActivityLocked方法:
final int startActivityLocked(IApplicationThread caller,
Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
String resultWho, int requestCode,
int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
boolean componentSpecified, ActivityRecord[] outActivity) {
......
ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
intent, resolvedType, aInfo, mService.mConfiguration,
resultRecord, resultWho, requestCode, componentSpecified, this);
......
err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
......
}
在startActivityLocked方法里,对传过来的参数做一些校验,然后创建ActivityRecord对象,再调用startActivityUncheckedLocked方法启动Activity:
final int startActivityUncheckedLocked(ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
boolean doResume, Bundle options, TaskRecord inTask) {
......
targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
......
return ActivityManager.START_SUCCESS;
}
targetStack指ActivityStack,然后调用ActivityStack的startActivityLocked方法:
final void startActivityLocked(ActivityRecord r, boolean newTask,
boolean doResume, boolean keepCurTransition, Bundle options) {
......
if (doResume) {
mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
}
}
通过一系列算法找出栈顶Activity,然后调用ActivityStackSupervisor的resumeTopActivitiesLocked显示栈顶的activity:
boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
Bundle targetOptions) {
if (targetStack == null) {
targetStack = getFocusedStack();
}
if (isFrontStack(targetStack)) {
result = targetStack.resumeTopActivityLocked(target, targetOptions);
}
......
return result;
}
接着调用ActivityStack的resumeTopActivityLocked方法显示栈顶的activity:
final boolean resumeTopActivityLocked(ActivityRecord prev) {
......
if (next.app != null && next.app.thread !=null){
......
}else{
......
startSpecificActivityLocked(next, true, true);
}
......
}
因为应用还未启动过,所以调用ActivityStack的startSpecificActivityLocked方法启动应用:
private final void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid);
......
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false);
}
然后调用ActivityManagerService的startProcessLocked方法启动应用:
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
String hostingType, ComponentName hostingName, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
}
最后调用到
private final void startProcessLocked(ProcessRecord app,
String hostingType, String hostingNameStr) {
......
try {
......
//Zygote孵化dalvik应用进程后,会执行android.app.ActivityThread类的main方法
Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, null);
......
} catch (RuntimeException e) {
......
}
}
然后调用Process的start方法开启一个进程:
public static final ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String[] zygoteArgs) {
try{
//通过socket方式通过Zygote进程孵化一个应用进程
startViaZygote(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo, zygoteArgs);
}catch (ZygoteStartFailedEx ex) {
......
}
}
然后以socket方式通过Zygote进程孵化一个应用进程并执行应用进程的main方法.
4.小结
到此就从activity的startActivity方法开始分析到一个新的应用进程的main方法执行的大概流程。下篇文章会从应用程序的main方法开始分析acticity启动过程中生命周期函数执行的过程。
网友评论