Activity启动流程
基于Android 11 源码分析
Android 7.0及以前采用代理模式,8.0及以后采用AIDL,ActivityManagerNative类被弃用,代理类ActivityManagerProxy已经被删除。
Android 11 使用了事务的方法进行整个流程的执行。
目录
文章目录
Activity界面: ####
1、Activity界面结构: #####
每一个Activity上面都有一个Window,可以通过getWindow获取
当setContentView设置显示后会回调Activity的onContentChanged方法
2、Android界面关系: #####
Window 类 位于 /frameworks/base/core/java/android/view/Window.java。该类是一个抽象类,提供了绘制窗口的一组通用API。可以将之理解为一个载体,各种View在这个载体上显示。它的唯一实现类则是PhoneWindow。
PhoneWindow类 位于/frameworks/policies/base/phone/com/android/internal/policy/impl/PhoneWindow.java。该类继承于Window类,是Window类的具体实现,即我们可以通过该类具体去绘制窗口。并且,该类内部包含了一个DecorView对象,该DectorView对象是所有应用窗口(Activity界面)的根View。 简而言之,PhoneWindow类是把一个FrameLayout类即DecorView对象进行一定的包装,将它作为应用窗口的根View,并提供一组通用的窗口操作接口。
DecorView类 该类是PhoneWindow类的内部类。该类继承FrameLayout,就是对普通的FrameLayout进行功能的扩展,更确切点可以说是修饰(Decor的英文全称是Decoration,即“修饰”的意思),比如说添加TitleBar(标题栏),以及TitleBar上的滚动条等 。最重要的一点是,它是所有应用窗口的根View 。DecorView则是由PhoneWindow负责添加。
打个比喻,Window类相当于一幅画(抽象概念,什么画我们未知) ,PhoneWindow为一副齐白石先生的山水画(具体概念,我们知道了是谁的、什么性质的画),DecorView则为该山水画的具体内容(有山、有水、有树,各种界面)。DecorView则呈现在PhoneWindow上。
3、Activity中Window创建过程: #####
Activity数据结构: ####
一、Activity中的关键数据结构: #####
1、数据结构类型: ######
ActivityRecord:Activity管理的最小单位,它一般对应一个用户界面。它需要记录AndroidManifest.xml中所定义的Activity的静态特征,同时也需要记录Activity在调度时的状态变化。ActivityRecord中的大部分成员变量都是记录Activity的相关信息成员变量final IApplicationToken.Stub appToken;可以看做是连接系统进程和应用进程的桥梁。
ActivityClientRecord:与ActivityRecord是在服务端(AMS)的记录相对应,是Activity在客户端(ActivityThread)的记录;
TaskRecord:它的职责就是管理ActivityRecord,记录activity开启的先后顺序。每个ActivityRecord都必须属于一个TaskRecord,TaskRecord与ActivityRecord是一对多的关系,栈顶的ActivityRecord表示当前用户可见的界面。TaskRecord中的成员变量final ArrayList mActivities;表示当前栈中管理的所有ActivityRecord。
ProcessRecord :记录着属于一个进程的所有ActivityRecord,运行在不同TaskRecord中的ActivityRecord可能属于同一个ProcessRecord。
ActivityStack:它的职责是管理TaskRecord。每个TaskRecord都必须属于一个ActivityStack,TaskRecord与ActivityStack是一对多的关系,栈顶的TaskRecord代表当前用户可见的任务。ActivityStack中的成员变量 private final ArrayList mTaskHistory = new ArrayList<>();表示当前栈中管理的所有TaskRecord。
ActivityDisplay:ActivityDisplay表示一个屏幕,Android支持三种屏幕:主屏幕,外接屏幕(HDMI等),虚拟屏幕(投屏)。一般情况下,即只有主屏幕时,ActivityStackSupervisor与ActivityDisplay都是系统唯一。
ActivityStackSupervisor:管理多个ActvityStack。
2、数据结构之间的关系: ######
Activity启动: ####
一、桌面点击启动Activity #####
首先Launcher进程向AMS请求创建根Activity,AMS会判断根Activity所需的应用程序进程是否存在并启动,如果不存在就会请求Zygote进程创建应用程序进程。应用程序进程启动后,AMS会请求应用程序进程创建并启动根Activity。
1、启动模型: ######
2、相关进程: ######
3、启动时序图(Android 8.0)(大图): ######
启动时序图(Android 11)(大图):
二、涉及到的类:
Instrumentation:负责调用Activity和Application生命周期。
ActivityStack:Activity在AMS的栈管理,用来记录已经启动的Activity的先后关系,状态信息等。通过ActivityStack决定是否需要启动新的进程。
ActivityThread:ActivityThread 运行在UI线程(主线程),App的真正入口。
ApplicationThread:继承IApplicationThread.Stub类,用来实现AMS和ActivityThread之间的交互。在ActivityManagerService需要管理相关Application中的Activity的生命周期时,通过ApplicationThread的代理对象与ActivityThread通讯。
IActivityManager:继承与IInterface接口,抽象出跨进程通信需要实现的功能。
ActivityStackSupervisor:负责所有Activity栈的管理。内部管理了mHomeStack、mFocusedStack和mLastFocusedStack三个Activity栈。其中,mHomeStack管理的是Launcher相关的Activity栈;mFocusedStack管理的是当前显示在前台Activity的Activity栈;mLastFocusedStack管理的是上一次显示在前台Activity的Activity栈
ActivityManagerService:负责管理四大组件和进程,包括生命周期和状态切换。AMS因为要和ui交互,所以极其复杂,涉及window。
具体流程(源码分析): ####
一、Launcher进程阶段: #####
Launcher通知AMS要启动activity。
Launcher.startActivitySafely->Activity.startActivity->Instrumentation.execStartActivity()->IActivityManager.startActivity->AMS.startActivityLauncher。
启动Activity最终是调用Activity.startActivity()方法,并设置intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);在新的栈Task中启动这个Activity。
Launcher请求 AMS 的时序图:
1、Launcher点击图标 ######
源码:packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
当我们点击应用程序的快捷图标时,就会调用 Launcher 的 startActivitySafely 方法,如下源码所示:
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
···
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //1
if (v != null) {
intent.setSourceBounds(getViewBounds(v));
}
try {
if (Utilities.ATLEAST_MARSHMALLOW
&& (item instanceof ShortcutInfo)
&& (item.itemType == Favorites.ITEM_TYPE_SHORTCUT
|| item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
&& !((ShortcutInfo) item).isPromise()) {
// Shortcuts need some special checks due to legacy reasons.
startShortcutIntentSafely(intent, optsBundle, item);
} else if (user == null || user.equals(Process.myUserHandle())) {
// Could be launching some bookkeeping activity
startActivity(intent, optsBundle);
} else {
LauncherAppsCompat.getInstance(this).startActivityForProfile(
intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
}
return true;
} catch (ActivityNotFoundException|SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
}
return false;
}
Launcher源码中可以看到启动Activity最终是调用Activity.startActivity()方法,并设置intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);在新的栈Task中启动这个Activity。
2、Activity: ######
源码:frameworks/base/core/java/android/app/Activity.java
Activity.startActivity方法最终调用startActivityForResult
// 源码 5643行
@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);
}
}
在 startActivity 方法中调用 startActivityForResult 方法,它的第二个参数为 -1,表示 Launcher 不需要知道 Activity 启动的结果。
…
private Instrumentation mInstrumentation;
…
// 源码6030行
public void startActivityForResult(
String who, Intent intent, int requestCode, @Nullable Bundle options) {
Uri referrer = onProvideReferrer();
if (referrer != null) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, who,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, who, requestCode,
ar.getResultCode(), ar.getResultData());
}
cancelInputsAndStartExitTransition(options);
}
当startActivityForResult()调用之后,实际上还是调用了mInstrumentation.execStartActivity()去执行启动操作;mMainThread.getApplicationThread()返回ActivityThead应用主线程的内部类ApplicationThread;ApplicationThread实现了IApplicationThread.StubAIDL接口方法,是App主线程ActivityThead对外提供(这里指AMS等系统服务)的操作接口,由此实现AMS对App的操作。
3、Instrumentation: ######
源码:frameworks/base/core/java/android/app/Instrumentation.java
Instrumentation是App与ATMS沟通的桥梁,内部通过ActivityTaskManager调取ATMS服务中的方法。每个Activity都持有Instrumentation对象的一个引用,但是整个进程只会存在一个Instrumentation对象。
// 源码1690行
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
···
try {
intent.migrateExtraStreamToClipData(who);
intent.prepareToLeaveProcess(who);
// 通过 ActivityTaskManager 调用 ATMS 的 startActivity 方法
int result = ActivityTaskManager.getService().startActivity(whoThread,
who.getBasePackageName(), who.getAttributionTag(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()), token, target,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
首先通过 ActivityTaskManager.getService()方法来获取 ATMS 的代理对象,接着调用 ATMS的 startActivity 方法。
4 、ActivityTaskManager获取ATMS服务启动 ######
源码:frameworks/base/core/java/android/app/ActivityTaskManager.java
// 源码149行
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityTaskManagerSingleton =
new Singleton<IActivityTaskManager>() {
@Override
protected IActivityTaskManager create() {
//获取一个AMS的binder对象
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
return am = IActivityTaskManager.Stub.asInterface(b);
}
};
先通过ServiceManager.getService获取一个AMS的binder对象,然后调用IActivityManager.Stub.asInterface。这些操作的作用就是使用AIDL进行IPC,与AMS进行通信。
getService在Android 5.0 中是ActivityManagerNative.getDefault()
在Android 7.0中getService()是:ActivityManager.getService()在Android 9.0及以上版本则是:ActivityTaskManager.getService()
Android 7.0 及以前用 AMS 的代理对象 ActivityManagerProxy 来与 AMS 进行进程间通信,Android 8.0 去除了 ActivityManagerNative 的内部类 ActivityManagerProxy,代替它的是 IActivityManager,IActivityManager.java 类是由 AIDL 工具在编译时自动生成的,它是 AMS 在本地的代理。
二、AMS(SystemServer进程)阶段: #####
ActivityManagerService.startActivity->ActivityManagerService.startActivityAsUser->ActivityStackSupervisor.startActivityMayWait->ActivityStackSupervisor.startActivityLocked(检查有没有在AndroidManifest中注册)->ActivityStackSupervisor.startActivityUncheckedLocked->ActivityStack.startActivityLocked(判断是否需要创建一个新的任务来启动Activity)->ActivityStack.resumeTopActivityLocked(获取栈顶的activity,并通知Launcher应该pause掉这个Activity以便启动新的activity)->ActivityStack.startPausingLocked->ApplicationThreadProxy.schedulePauseActivity
1、ActivityTaskManagerService启动Activity ######
源码:frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
ATMS中有mActivityStarter和mUserController两个变量,UserController用户系统多用户的管理以及权限的管理,ActivityStarter加载Activity的控制类。
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
final ActivityStarter mActivityStarter;
final UserController mUserController;
…
//构造函数中
mActivityStarter = new ActivityStarter(this, mStackSupervisor);
mUserController = new UserController(this);
…
// 源码1042行
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
…
// 源码1077行
private int startActivityAsUser(IApplicationThread caller, String callingPackage,
@Nullable String callingFeatureId, Intent intent, String resolvedType,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
assertPackageMatchesCallingUid(callingPackage);
enforceNotIsolatedCaller(“startActivityAsUser”);
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setCallingFeatureId(callingFeatureId)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setUserId(userId)
// 调用 ActivityStarter 的 execute 方法
.execute();
}
…
}
在getActivityStartController方法中返回的ActivityStartController,然后调用obtainStarter获取ActivityStarter对象,ATMS 根据这个 UserId 来确定调用者的权限。
最后调用了 ActivityStarter 的 startActivityLocked 方法,startActivityLocked 方法的参数要比 startActivityAsUser 多几个,需要注意的是倒数第二个参数类型为 TaskRecord,代表启动的 Activity 所在的栈。最后一个参数"startActivityAsUser" 代表启动的理由。
2、ActivityStarter管理Activity启动 ######
<