startActivity(Intent intent)启动一个Activity,然后会通过Instrumentaion和ActivityTaskManagerService通信,通过ActivityStarter执行启动流程。
流程图:
ActivityStarter在executeRequest()方法中实例化ActivityRecord, ActivityStack。
ActivityRecord,ActivityStack关系图
ActivityRecord,ActivityStack类关系图:
Token
ActivityRecord继承WindowToken类,在ActivityRecord构造函数中通过Intent参数初始化WindowToken的token变量,token是一个IBinder对象。
//WindowToken.java
class WindowToken extends WindowContainer<WindowState> {
// The actual token.
final IBinder token;
}
尽管ActivityRecord继承了WindowToken对象,但是它还是另外声明了一个自己的Token变量appToken,appToken和父类WindowToken的token变量都在ActivityRecord对象的构造方法中初始化,他们指向同一个实例化的对象,appToken是ActivityRecord的嵌套类ActivityRecord.Token,对比IBinder多实现了一些自己的方法attach(ActivityRecord activity);tokenToActivityRecordLocked(Token token);toString()等。
//ActivityRecord.java
final class ActivityRecord extends WindowToken implements WindowManagerService.AppFreezeListener {
// TODO: rename to mActivityToken
final ActivityRecord.Token appToken;
ActivityRecord() {
super(_service.mWindowManager, new Token(_intent).asBinder(), TYPE_APPLICATION, true,
null /* displayContent */, false /* ownerCanManageAppTokens */);
appToken = (Token) token;
}
static class Token extends IApplicationToken.Stub {
private WeakReference<ActivityRecord> weakActivity;
private final String name;
private final String tokenString;
Token(Intent intent) {
name = intent.getComponent().flattenToShortString();
tokenString = "Token{" + Integer.toHexString(System.identityHashCode(this)) + "}";
}
}
}
//IApplicationToken.aidl
interface IApplicationToken
{
String getName();
}
Token为什么是binder对象?
可以理解为Token的设计目的是为了唯一的指定一个Activity,在Activity启动到显示的过程中,Token在ActivityRecord实例化的同时被初始化,后面还有许多地方都需要Token对象:
ClientTransaction.obtain(next.app.getThread(), next.appToken); //next.appToken被赋值给Activity.mToken
addWindow()
在Android系统中,binder不仅仅用来跨进程通信,binder对象的一个有趣属性是,每个实例在系统中的所有进程中都维护一个惟一的标识,无论它跨越了多少进程边界或它去了哪里,这为系统的安全性做出了保证,不能被伪造,避免了安全漏洞,这不是String对象能够做到的。参考:https://www.androiddesignpatterns.com/2013/07/binders-window-tokens.html#footnote5
可以理解为Activity, ActivityRecord, Token都是一一对应的关系。
ActivityRecord,ActivityStack初始化
ActivityStack在ActivityStarter类的startActivityInner()方法中被实例化,赋值给其mTargetStack变量:
if (mTargetStack == null) {
mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags, targetTask, mOptions);
}
ActivityStack被实例化后,父类WindowContainer回调子类ActivityRecord和Task覆盖的onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent)方法,初始化ActivityRecord中的类变量task,Task中的类变量mResumedActivity。ActivityRecord类和Task类就这样相互关联起来了。父类WindowContainer的类变量mChildren也被更新,mChildren保存着当前WindowContainer实例的所有Task对象。
//ActivityRecord.java
@Override
void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) {
final Task oldTask = oldParent != null ? (Task) oldParent : null;
final Task newTask = onParentChanged != null ? (Task) newParent : null;
this.task = newTask;
...
}
//Task.java
@Override
void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) {
...
if (newParent != null) {
final Task newParentTask = ((WindowContainer) newParent).asTask();
if (newParentTask != null) {
final ActivityRecord top = newParentTask.getTopNonFinishingActivity(
false /* includeOverlays */);
if (top != null && top.isState(RESUMED)) {
newParentTask.setResumedActivity(top, "addedToTask");
}
}
...
}
...
}
ActivityRecord和ActivityStack都被初始化后,RootWindowContainer通过父类WindowContainer的类变量mChildren判断当前需要被显示的ActivityStack,调用其resumeTopActivityUncheckedLocked()方法。
隐藏其他Activity
在一个Activity显示出来之前,需要隐藏之前显示的Activity,回调其onPause()方法。
ActivityStack对象resumeTopActivityInnerLocked()方法中,通过TaskDisplayArea.pauseBackStacks(userLeaving, next);,遍历mChildren中所有的Task对象,判断这些Task中是否存在mResumedActivity,如果存在,通过ClientLifecycleManager隐藏这个Activity。PauseActivityItem在execute()后,postExecute()方法会继续调用RootWindowContainer类的resumeFocusedStacksTopActivities()方法,执行对应Activity的显示操作。
进程,线程初始化
在一个Activity显示出来之前,需要确定进程和主线程是否已经准备好。
通过ActivityRecord类的attachedToProcess()方法判断当前ActivityRecord对象的进程和线程是否准备好,如果准备好了,通过ApplicationThread和appToken参数与应用进程通信,回调对应生命周期方法(onNewIntent()等),ClientLifecycleManager执行ResumeActivityItem事务,否则需要调用ActivityStackSupervisor类startSpecificActivity()方法进一步判断进程和线程状态,调用ActivityTaskManagerService.startProcessAsync()启动新进程。
//ActivityRecord.java
boolean hasProcess() {
return app != null;
}
boolean attachedToProcess() {
return hasProcess() && app.hasThread();
}
//ActivityStack.java
@GuardedBy("mService")
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...
boolean pausing = taskDisplayArea.pauseBackStacks(userLeaving, next);
if (mResumedActivity != null) {
pausing |= startPausingLocked(userLeaving, false /* uiSleeping */, next);
}
if (pausing) {
...
}
if (next.attachedToProcess()) {
try{
final ClientTransaction transaction =
ClientTransaction.obtain(next.app.getThread(), next.appToken); //ApplicationThread!
// Deliver all pending results.
ArrayList<ResultInfo> a = next.results;
if (a != null) {
final int N = a.size();
if (!next.finishing && N > 0) {
if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
"Delivering results to " + next + ": " + a);
transaction.addCallback(ActivityResultItem.obtain(a));
}
}
if (next.newIntents != null) {
transaction.addCallback(
NewIntentItem.obtain(next.newIntents, true /* resume */)); //onNewIntent()
}
transaction.setLifecycleStateRequest(
ResumeActivityItem.obtain(next.app.getReportedProcState(),
dc.isNextTransitionForward()));
mAtmService.getLifecycleManager().scheduleTransaction(transaction);
} catch (Exception e) {
mStackSupervisor.startSpecificActivity(next, true, false);
return true;
}
} else {
mStackSupervisor.startSpecificActivity(next, true, true);
}
return true;
}
system_server进程和zygote进程通信后,zygote以“android.app.ActivityThread”为入点fork出一个新的进程,新进程启动首先调用ActivityThread的main()方法。其中Looper.prepareMainLooper(); Looper.loop();初始化主线程。
// ActivityThread.java
@UnsupportedAppUsage
final ApplicationThread mAppThread = new ApplicationThread();
public static void main(String[] args) {
// Install selective syscall interception
AndroidOs.install();
...
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
Looper.loop();
}
@UnsupportedAppUsage
private void attach(boolean system, long startSeq) {
...
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
}
thread.attach(false, startSeq);获取系统服务AMS对象attachApplication(),传递的参数mAppThread是一个ApplicationThread对象,ApplicationThread是ActivityThread的内部类,也是一个Binder对象。在此处它是作为Activitythread和AMS通信的桥梁,ApplicationThread和ActivityThread二者间通过Handler
“H”通信。
//ActivityManagerService.java
@GuardedBy("this")
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
...
AppDeathRecipient adr = new AppDeathRecipient(
app, pid, thread);
thread.asBinder().linkToDeath(adr, 0);
app.deathRecipient = adr;
...
thread.bindApplication(processName, appInfo, providerList,
instr2.mClass,
profilerInfo, instr2.mArguments,
instr2.mWatcher,
instr2.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.compat, getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions,
app.mDisabledCompatChanges);
...
app.makeActive(thread, mProcessStats);
mProcessList.updateLruProcessLocked(app, false, null);
...
}
attachApplicationLocked()创建app死亡通知AppDeathRecipient(进程被杀死后通知AMS),通过thread(IApplicationThread对象)与app进程通信bindApplication(),ActivityThread调用handleBindApplication(),最终会回调Application对象的onCreate()生命周期方法。
更新对应进程的LRU,OomAdj等相关属性,调用ProcessRecord对象makeActive(thread, mProcessStats);方法,将thread对象赋值给WindowProcessController类的mThread变量。
//WindowProcessController.java
// The actual proc... may be null only if 'persistent' is true (in which case we are in the
// process of launching the app)
private IApplicationThread mThread;
到这里进程和线程都已经准备好了,是时候真正启动Activity了。
realStartActivityLocked
//ActivityStackSupervisor.java
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
...
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
r.assistToken, r.createFixedRotationAdjustmentsIfNeeded()));
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
...
}
ClientTransaction对象添加LaunchActivityItem回调,LaunchActivityItem.execute()方法中会调用ActivityThread的handleLaunchActivity()方法,最后会调用Activity的生命周期方法onCreate()。
ClientTransaction对象setLifecycleStateRequest(ResumeActivityItem),设置Activity的resume状态。
最终ActivityThread调用handleResumeActivity()方法通过系统服务WMS的addView()方法显示Activity界面。
//ActivityThread.java
@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
...
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
final Activity a = r.activity;
if (r.window == null && !a.mFinished && willBeVisible) {
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
wm.addView(decor, l);
} else {
// The activity will get a callback for this {@link LayoutParams} change
// earlier. However, at that time the decor will not be set (this is set
// in this method), so no action will be taken. This call ensures the
// callback occurs with the decor set.
a.onWindowAttributesChanged(l);
}
}
}
...
}
performResumeActivity()方法中会通过Instrumentation回调Activity中的onResume()和onPostResume()方法,然后才是addView(),可见在生命周期方法onResume()和onPostResume()被调用时,当前Activity对用户依然是不可见的。
Activity启动流程中可以看到system_server, zygote, app三个进程相互通信协作,ActivityTaskManagerService, ActivityManagerService, WindowManagerService等关键服务协同工作,token作为Activity的唯一标识贯穿其中。