Activity启动流程(API28)

Activity的启动是Activity与ActivityManagerService之间多次通讯的结果。
Activity的启动流程在API28以后变成了事务启动的方式


Activity.java

startActivity
startActivity
startActivityForResult
startActivityForResult

Instrumentation.java

Instrumentation从字面上来看是仪器盘的意思,具体到程序中是管理activity的一个工具类,包括创建和启动Activity,activity的生命周期方法都是由Instrumentation这个仪器来控制,一个进程中只用一个Instrumentation实例。

execStartActivity
ActivityManager.getService().startActivity

//其中有contextThread和token两个参数,AMS反过来通知的时候需要这俩参数

checkStartActivityResult
//检查启动Activity的结果(抛出异常,例如清单文件未注册Activity)
//通过IActivityManagerSingleton.get()得到ActivityManagerProxy(IActivityManager)代理对象,IActivityManager 是应用程序进程与 SystemServer(AMS 所在进程)通信的 Binder 在 Client 端的代理,因为是应用程序进程向 AMS 发消息,所以应用程序进程是 Client 端。反过来是ApplicationThreadProxy

AMS.java

startActivity
startActivityAsUser
startActivityAsUser
mActivityStartController.obtainStarter……
.setMayWait(userId) //这一步如下
.execute();

//ActivityStarter.java
ActivityStarter setMayWait(int userId) {
mRequest.mayWait = true;
mRequest.userId = userId;
return this;
}

ActivityStarter.java

int execute()
// 因为mRequest.mayWait = true,所以调用startActivityMayWait

startActivityMayWait
//根据intent在系统中找到合适的应用的activity,如果有多个activity可选择,则会弹出ResolverActivity让用户选择合适的应用。

ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
startActivity-1
startActivity-2
ActivityRecord r = new ActivityRecord(……)

//创建ActivityRecord对象,在AMS中,将用ActivityRecord来作为Activity的记录者,每次启动一个Actvity会有一个对应的ActivityRecord对象

startActivity-3
startActivityUnchecked

//startActivityUnchecked方法负责调度ActivityRecord和Task,理解该方法是理解Actvity启动模式的关键。startActivityUnchecked方法调度task的算法非常复杂,和当前回退栈,要启动的acitivity的启动模式以及taskAffinity属性,启动activity时设置的intent的flag等诸多要素相关

postStartActivityProcessing
//此处将通知ActivityStarter, Activity对应的Task被移动到前台

mTargetStack.startActivityLocked
//调用WMS准备App切换相关的工作

mSupervisor.resumeFocusedStackTopActivityLocked

ActivityStackSupervisor.java

resumeFocusedStackTopActivityLocked

~~~targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); ~~~mFocusedStack.resumeTopActivityUncheckedLocked(null, null);

//待启动Activity对应的Task为前台Task时,调用该Task对应ActivityStack的resumeTopActivityUncheckedLocked
//否则只是调用当前前台栈的resumeTopActivityUncheckedLocked

ActivityStack.java

resumeTopActivityUncheckedLocked
resumeTopActivityInnerLocked

//mResumedActivity指向上一次启动的Activity(比如Launcher或者前一个Activity)
//通知Launcher或者前一个Activity进入pause状态
if (mResumedActivity != null) {
pausing |= startPausingLocked(userLeaving, false, next, false);
}

//Launcher或者前一个Activity已经暂停了
if (pausing) {
if (next.app != null && next.app.thread != null) {
//如果app已经启动过,提高待启动Activity所在进程的优先级,保证其不被kill
mService.updateLruProcessLocked(next.app, true, null);
}
}

//这里比较复杂
if (next.app != null && next.app.thread != null) {
……
//假设App已启动,点击Home键返回到Launcher,再次从Launcher启动app
mStackSupervisor.scheduleResumeTopActivities();
……
}else{
……
mStackSupervisor.startSpecificActivityLocked(next, true, true);
……
}

ActivityStackSupervisor.java

startSpecificActivityLocked

ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
if (app != null && app.thread != null) {
realStartActivityLocked
//目标Activity的App已经启动(存在ActivityThread),则启动Activity
return;
}
mService.startProcessLocked

//如果进程不存在,则通过zygote创建应用进程。
//从Launcher冷启动app,则需要创建新进程


我们假设进程不存在

1.调用AMS的startProcessLocked方法

2.Process.java的start函数,将通过socket发送消息给zygote

3.zygote将派生出一个子进程,子进程将通过反射调用ActivityThread的main函数,在该方法里会先准备好Looper和消息队列,然后调用attach方法将ApplicationThread绑定到AMS,然后进入loop循环,不断地读取消息队列里的消息,并分发消息。


ActivityThread.java

public static void main(String[] args) {
……
Looper.prepareMainLooper();
//准备主线程的Looper
ActivityThread thread = new ActivityThread();
//创建当前进程的ActivityThread
thread.attach(false);
//将ApplicationThread绑定到AMS
//这样AMS就可以通过ApplicationThread代理对象控制应用进程
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
//保存当前进程的主线程的Handler
……
Looper.loop();
//开启主线程的消息循环
……
}

AMS.java

attachApplication
attachApplicationLocked

//因为进程由AMS启动,所以在AMS中一定会有ProcessRecord(app进程记录)
//如果没有ProcessRecord,则需要杀死该进程并退出
if (app == null) {
……
return false;
}

//如果从ProcessRecord中获取的IApplicationThread不为空,有可能旧应用进程刚释放,内部IApplicationThread尚未清空,需要去清空
if (app.thread != null) {
handleAppDiedLocked(app, true, true);
}

……
try{
//绑定Application到ActivityThread
thread.bindApplication
}catch{
//重启进程,和ActivityStackSupervisor.java中的一样
startProcessLocked
}

try {
//启动Activity
if (mStackSupervisor.attachApplicationLocked(app)) {
//didSomething表示是否有启动四大组件
didSomething = true;
}
} catch (Exception e) {
badApp = true;
}

//绑定service和Broadcast的Application

if (badApp) {
//如果以上组件启动出错,则需要杀死进程并移除记录
app.kill(“error during init”, true);
handleAppDiedLocked(app, false, true);
return false;
}

//如果以上没有启动任何组件,那么didSomething为false
if (!didSomething) {
updateOomAdjLocked();
}

//调整进程的oom_adj值, oom_adj相当于一种优先级
//如果应用进程没有运行任何组件,那么当内存出现不足时,该进程是最先被系统“杀死”

2个重点方法:

AMS.java——thread.bindApplication

//ActivityThread内部类ApplicationThread的bindApplication被调用,通过handler发送消息,将逻辑转移到主线程handleBindApplication

//获取LoadeApk对象
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);

//创建进程对应的Android运行环境ContextImpl对象
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);

//创建Instrumentation监控android生命周期(一个进程对应一个Instrumentation实例)
if ((InstrumentationInfo)ii != null) {
……
} else {
mInstrumentation = new Instrumentation();
}

//创建Application
Application app;
app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;

//加载进程对应中的ContentProvider
installContentProviders(app, data.providers);

mInstrumentation.onCreate(data.instrumentationArgs);

//调用Application的onCreate方法
mInstrumentation.callApplicationOnCreate(app);

ActivityStackSupervisor.java——attachApplicationLocked

//App创建好了之后,开始启动Activity
//前台待启动的Activity与当前新建的进程一致时,启动这个Activity
if (activity.app == null && app.uid == activity.info.applicationInfo.uid&& processName.equals(activity.processName)) {
try {
if (realStartActivityLocked(activity, app,
top == activity /* andResume /, true / checkConfig */)) {
didSomething = true;
}


Activity的启动流程在API28以后变成了事务启动的方式

clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, mService.isNextTransitionForward(),
profilerInfo));

mService.getLifecycleManager().scheduleTransaction(clientTransaction);

ClientLifecycleManager.java

scheduleTransaction(ClientTransaction transaction) throws RemoteException

ClientTransaction.java

public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}

ActivityThread.java / ApplicationThread

@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}

ClientTransactionHandler.java

void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}

ActivityThread.java / H

case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
if (isSystem()) {
transaction.recycle();
}
break;

TransactionExecutor.java

public void execute(ClientTransaction transaction) {
final IBinder token = transaction.getActivityToken();
log(“Start resolving transaction for client: “ + mTransactionHandler + “, token: “ + token);
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
log(“End resolving transaction”);
}

executeCallbacks(ClientTransaction transaction)

item.execute(mTransactionHandler, token, mPendingActions);

LaunchActivityItem.java

@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, “activityStart”);
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mIsForward,
mProfilerInfo, client);
client.handleLaunchActivity(r, pendingActions, null);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}


ActivityThread.java

handleLaunchActivity
performLaunchActivity

//它是Context的具体实现,ContextImpl是通过Activity的attach方法来和Activity建立关联的,在attach方法中Activity还会完成Window的创建并建立和Window的关联,这样当Window接收到外部输入事件后就可以将事件传递给Activity。
ContextImpl appContext = createBaseContextForActivity(r);

//从ActivityClientRecord中获取待启动的Activity的组件信息
//通过Instrumentation的newActivity方法使用类加载器创建Activity对象
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);

//Instrumentation.java
getFactory(pkg).instantiateActivity(cl, className, intent);

//AppComponentFactory.java
(Activity) cl.loadClass(className).newInstance();

//创建application(其实在handleBindApplication中已经创建完成,直接返回实例)
Application app = r.packageInfo.makeApplication(false, mInstrumentation);

//Instrumentation.java
app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);

//AppComponentFactory.java
(Application) cl.loadClass(className).newInstance();

//创建phonewindow,给winodw绑定windowmanager
activity.attach

//调用Activity的onCreate方法
mInstrumentation.callActivityOnCreate(activity, r.state);
activity.performCreate(icicle);
performCreate(icicle, null);
onCreate(icicle);


补充:

onCreate -> onStart -> onResume 核心逻辑

结合mStackSupervisor.realStartActivityLocked,这里有关LaunchActivityItem和ResumeActivityItem的设置

TransactionExecutor.java

#executeCallbacks(transaction);
—LaunchActivityItem.execute(这一步的cycleToPath不会执行)(onCreate)
#executeLifecycleState(transaction);
—cycleToPath执行(onStart)
—ResumeActivityItem.execute(onResume)

可以参考:https://juejin.cn/post/6844903959589552142#heading-11