一、Activity的生命周期
对于每个Android开发者来说,Activity的生命周期最熟悉不过了,这里简单引用一下Android API文档上的生命周期图。但是Activity的几个主要生命周期是如何回调的呢?请看下面Activity的启动流程部分。
f
二、Activity的启动流程
Activity的启动一般我们是通过startActivity(Intentent),为了分析主流程,这里暂时以Activity的冷启动来分析。跟进startActivity()的内部,看看具体是如何startActivity的,在Activity中startActivity通过前面几次方法的内部调用,会走到下面方法,伪代码如下:
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
if (mParent == null) {
...
//冷启动走这里
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
} 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);
}
}
}
核心方法在Instrumentation的exeStartActivity方法,该方法中通过AMS的binder对象调用AMS中的startActivity方法,代码块如下
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
...
//核心方法通过AMS的binder对象调用AMS中的startActivity方法
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, null, options);
}
这里AMS的binder对象调用会通过mRemote.transact(START_ACTIVITY_TRANSACTION, data, relplay, 0)来调用到ActivityManagerNative中的onTransact()方法,如下
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case START_ACTIVITY_TRANSACTION:
{
...
//核心方法startActivity
int result = startActivity(app, callingPackage, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags,
profileFile, profileFd, options);
return true;
}
...
}
上面核心方法startActivity最后走到AMS中的startActivity方法,方法如下
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());
}
startActivityAsUser的实现如下
@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) {
...
//核心方法调用
return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
null, null, options, userId);
}
这里ActivityStackSupervisor我理解为一个Activity的辅助类,这里省去中间一些跳转,最终于调用startSpecificActivityLocked
在com.android.server.am.ActivityStackSupervisor.java中
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
//查询该Activity所对应的进程是否启动
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
//在ProcessRecord不为null说明进程已经存在,app.thread != null,说明应用向AMS注册过IApplicationThread.
if (app != null && app.thread != null) {
realStartActivityLocked(r, app, andResume, checkConfig);
}
//否则启动进程,在AMS中启动
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
当进程不存在的时候则执行mService.startProcessLocked(),即在AMS中执行,方法如下
private final void startProcessLocked(ProcessRecord app,
String hostingType, String hostingNameStr) {
...
// Start the process. It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
//android.app.ActivityThread为进程启动入口函数类, Process.start()向Zygote发送一个启动进程的请求
Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, null);
...
synchronized (mPidsSelfLocked) {
this.mPidsSelfLocked.put(startResult.pid, app);
Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
msg.obj = app;
//如果应用进程启动后,在一定时间内没有向AMS来报告就会超时,10秒,
// 如果超时,AMS则会清理应用的相关信息(如该进程启动的一些应用组件)
mHandler.sendMessageDelayed(msg, startResult.usingWrapper
? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
}
}
这里继续看一下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) {
return startViaZygote(processClass, niceName, uid, gid, gids,
}
private static ProcessStartResult startViaZygote(final String processClass,
final String niceName,
final int uid, final int gid,
final int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String[] extraArgs) {
...
return zygoteSendArgsAndGetResult(argsForZygote);
}
zygoteSendArgsAndGetResult()已经执行到Zygote端了,实际上是Zygote进程的Loop循环中调用了进程启动的方法runOnce()函数,从而启动APP应用进程。进一步会调用到ActivityThread的main函数
public static void main(String[] args) {
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
//这里会向AMS报告,按前面Handler sendMessage 10秒超时,如果在10少还没有来得及注册,那AMS则会清理掉该进程的相关信息
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
上面说这么多,关于startActivity时启动进程的流程,这里通过一张图来总结一下AMS、Zygote、应用之间的通信关系
应用程序向AMS作attachApplication操作的实现如下,已在注释中说明清楚
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
...
//根据进程pid获取进程
ProcessRecord app = mPidsSelfLocked.get(pid);
...
//thread为应用端注册到AMS的binder对象
//应用端作一些初始化,比如初始化Application
thread.bindApplication(processName, appInfo,...);
...
//下面这三步处理启动进程时挂起的一些应用组件
//处理挂起的Activity组件
mStackSupervisor.attachApplicationLocked(app, mHeadless);
...
//处理挂起的Service组件
mServices.attachApplicationLocked(app, processName);
...
//处理挂起的广播组件
sendPendingBroadcastsLocked(app);
return true;
}
这里以Launcher启动应用为例子,当Launcher发起startActivity时,由AMS向检测进程是否启动,如果没有启动,则发起启动进程的请求startProcessLocked,进入Zygote的runOnce()函数fork出应用进程,然后调用ActivityThread的main()函数开始Application向AMS注册,即attachApplication,继续后面的bindApplication, makeApplication。从而进程启动完成。
当进程启动完成后,就是真正的启动Activity了,即执行realStartActivityLocked()。看看realStartActivityLocked()是什么样的。
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) {
...
//这里app对应ProcessLocked,即应用进程
//app.thread对应ApplicationThread,即应用程序启动时册到AMS的binder对象
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
new Configuration(mService.mConfiguration), r.compat,
app.repProcState, r.icicle, results, newIntents, !andResume,
mService.isNextTransitionForward(), profileFile, profileFd,
profileAutoStop);
...
return true;
}
上面scheduleLaunchActivity最后会调用到ActivityThread中的scheduleLaunchActivity(),具体如下
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
int procState, Bundle state, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
...
ActivityClientRecord r = new ActivityClientRecord();
...
//给主线程发送一个启动Activity的消息
sendMessage(H.LAUNCH_ACTIVITY, r);
}
public void handleMessage(Message msg) {
switch (msg.what) {
case LAUNCH_ACTIVITY: {
ActivityClientRecord r = (ActivityClientRecord) msg.obj;
handleLaunchActivity(r, null);
}
break;
}
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
}
}
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
//1、调用到Activity生命在中的onCreate()方法,内部通过ClassLoader加载Activity到实例
//2、中间还会检测Application, 创建Activity的上下文,实际就是Application中的mBase
//3、然后通过Instrumentation中的callActivityOnCreate()调用到onCreate(),以及Instrumentation的callActivityOnStart()调用到onStart()
Activity a = performLaunchActivity(r, customIntent);
...
if (a != null) {
//这里实际上会调用到我们平常看到的Activity中的生命周期方法onResume()
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
}
}
经过上面步骤,很清楚的看到Activity的主要生命周期方法onCreate()、onStart()、onResume()是在何时调用。用一张图来总结Activity在启动进程后如何realStartActivityLock()的
对于整个Activity的启动,其实可以一句话总结:先判断Activity的进程有没有启动,如果没有走启动进程的流程,否则走真正启动Activity的流程。
Activity的启动看似很复杂,其实核心流利就两个,就是上面的两张图表示。