本文基于Android 11.0源码分析
前言
Activity启动过程是AMS系统中一个重要的代码流程,本篇文档将对该流程作详细的分析。根据Activity的启动时机,从如下两个方面入手:
- 根Activity的启动流程:又叫应用程序启动流程,即点击桌面上某一个应用图标到应用第一个Activity展示出来的流程;
- 普通Activity的启动流程:即应用内启动一个Activity到展示出来的流程。
由于两种启动流程是有重叠的,根Activity的启动流程更复杂,所以下面我们基于 Android R(11.0) 重点分析根Activity的启动流程,而普通Activity的启动流程在涉及的地方会稍微提一下。
应用的启动流程大致分为下面五个阶段:
(1)应用启动进程Launcher调用ATMS系统进程的过程;
(2)ATMS向AMS发送创建应用进程的过程;
(3)AMS向Zygote进程发送创建应用进程ActivityThread的过程;
(4)Zygote进程接收请求 fork 并启动应用进程ActivityThread的过程;
(5)应用进程ActivityThread启动Activity的过程。
1.应用启动进程Launcher调用ATMS系统进程的过程
Launcher是一个用于显示所有应用程序的一个系统级别的应用程序,也就是我们常说的桌面,通过 PackageManagerService来获取已安装的所有应用程序信息。实际上就是一个Activity,由 AMS(ActivityManagerService)来管理进程调度与启动,AMS是Android 中最核心的系统服务,几乎所有的应用都需要与AMS 通信。
根Activity的启动流程其实就是点击Launcher中某一个应用图标到应用第一个Activity展示出来的流程,当系统开机后,Launcher也会被AMS启动,然后将已经安装的应用程序图标显示到桌面上,所以当我们点击一个应用图标其实就是相当于点击Activity中的一个Button,其相应事件就是Launcher进程请求ATMS来启动该应用程序。
1.1 时序图
1.2 Launcher桌面的App图标入口
从源码看一下Launcher桌面是不是如我们所说的是一个Activity,源码如下:
// packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
/**
* Default launcher application.
*/
public class Launcher extends StatefulActivity<LauncherState> implements LauncherExterns,
Callbacks, InvariantDeviceProfile.OnIDPChangeListener, PluginListener<OverlayPlugin>,
LauncherOverlayCallbacks {
@Override
@TargetApi(Build.VERSION_CODES.S)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......
// 分析1 -- 加载、展示布局文件
inflateRootView(R.layout.launcher);
}
}
/**
* Abstract activity with state management
* @param <STATE_TYPE> Type of state object
*/
public abstract class StatefulActivity<STATE_TYPE extends BaseState<STATE_TYPE>>
extends BaseDraggingActivity {}
/**
* Extension of BaseActivity allowing support for drag-n-drop
*/
@SuppressWarnings("NewApi")
public abstract class BaseDraggingActivity extends BaseActivity
implements OnColorsChangedListener, DisplayInfoChangeListener {}
/**
* Launcher BaseActivity
*/
public abstract class BaseActivity extends Activity implements ActivityContext {}
分析1 - 正如我们所说,Launcher就是一个Activity,加载的布局为R.layout.launcher,布局文件如下:
<!-- R.layout.launcher -->
<?xml version="1.0" encoding="utf-8"?>
<com.android.launcher3.LauncherRootView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:id="@+id/launcher"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<com.android.launcher3.dragndrop.DragLayer
android:id="@+id/drag_layer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:importantForAccessibility="no">
<!-- 这里是展示所有 App 图标的布局,我们只看相关代码 -->
<include
android:id="@+id/apps_view"
layout="@layout/all_apps"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.android.launcher3.dragndrop.DragLayer>
</com.android.launcher3.LauncherRootView>
----------------------------------------------------------------
<!-- R.layout.apps_view -->
<?xml version="1.0" encoding="utf-8"?>
<com.android.launcher3.allapps.LauncherAllAppsContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/apps_view"
android:theme="?attr/allAppsTheme"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="true"
android:clipToPadding="false"
android:focusable="false"
android:saveEnabled="false">
<!-- 展示所有已安装app的AllAppsRecyclerView继承自RecyclerView -->
<include
layout="@layout/all_apps_rv_layout"
android:visibility="gone" />
</com.android.launcher3.allapps.LauncherAllAppsContainerView>
----------------------------------------------------------------
<!-- R.layout.all_apps_rv_layout -->
<?xml version="1.0" encoding="utf-8"?>
<com.android.launcher3.allapps.AllAppsRecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/apps_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/search_container_all_apps"
android:clipToPadding="false"
android:descendantFocusability="afterDescendants"
android:focusable="true" />
这下面就要看看这个AllAppsRecyclerView怎么设置适配器 Adapter,以及点击事件在哪里设置?
AllAppsRecyclerView外层是LauncherAllAppsContainerView,它是AllAppsContainerView的子类。给 AllAppsRecyclerView设置Adapter被封装到了AllAppsContainerView里面,看一下代码:
// packages/apps/Launcher3/src/com/android/launcher3/allapps/AllAppsContainerView.java
public class AllAppsContainerView extends SpringRelativeLayout implements DragSource,
Insettable, OnDeviceProfileChangeListener, OnActivePageChangedListener,
ScrimView.ScrimDrawingController {
protected void rebindAdapters(boolean force) {
......
if (mUsingTabs) {
......
// 这里只分析不使用 Tabs 的情况,感兴趣的童鞋可以继续追源码
} else {
// AllAppsRecyclerView设置Adapter等信息
mAH[AdapterHolder.MAIN].setup(findViewById(R.id.apps_list_view), null);
mAH[AdapterHolder.WORK].recyclerView = null;
}
......
}
public class AdapterHolder {
public static final int MAIN = 0;
public static final int WORK = 1;
public final AllAppsGridAdapter adapter;
final LinearLayoutManager layoutManager;
final AlphabeticalAppsList appsList;
AllAppsRecyclerView recyclerView;
AdapterHolder(boolean isWork) {
mIsWork = isWork;
appsList = new AlphabeticalAppsList(mLauncher, mAllAppsStore,
isWork ? mWorkManager.getAdapterProvider() : null);
BaseAdapterProvider[] adapterProviders =
isWork ? new BaseAdapterProvider[]{mSearchAdapterProvider,
mWorkManager.getAdapterProvider()}
: new BaseAdapterProvider[]{mSearchAdapterProvider};
// 创建adapter
adapter = new AllAppsGridAdapter(mLauncher, getLayoutInflater(), appsList,
adapterProviders);
appsList.setAdapter(adapter);
layoutManager = adapter.getLayoutManager();
}
void setup(@NonNull View rv, @Nullable ItemInfoMatcher matcher) {
appsList.updateItemFilter(matcher);
recyclerView = (AllAppsRecyclerView) rv;
recyclerView.setEdgeEffectFactory(createEdgeEffectFactory());
recyclerView.setApps(appsList);
recyclerView.setLayoutManager(layoutManager);
// AllAppsRecyclerView 设置 AllAppsGridAdapter
recyclerView.setAdapter(adapter);
}
}
}
源码中在AllAppsContainerView中为AllAppsRecyclerView设置了AllAppsGridAdapter,然后在AllAppsGridAdapter #onCreateViewHolder()方法中为子项itemView设置点击事件,点击事件由launcher.getItemOnClickListener()方法获取(BaseDraggingActivity.java#ItemClickHandler.INSTANCE)。看一下ItemClickHandler是怎么处理点击事件的,代码如下:
// packages/apps/Launcher3/src/com/android/launcher3/touch/ItemClickHandler.java
public class ItemClickHandler {
private static final String TAG = ItemClickHandler.class.getSimpleName();
/**
* Instance used for click handling on items
* 单例方式获取点击事件
*/
public static final OnClickListener INSTANCE = ItemClickHandler::onClick;
private static void onClick(View v) {
if (v.getWindowToken() == null) return;
Launcher launcher = Launcher.getLauncher(v.getContext());
if (!launcher.getWorkspace().isFinishedSwitchingState()) return;
Object tag = v.getTag();
if (tag instanceof WorkspaceItemInfo) {
onClickAppShortcut(v, (WorkspaceItemInfo) tag, launcher);
} else if (tag instanceof FolderInfo) {
if (v instanceof FolderIcon) {
onClickFolderIcon(v);
}
} else if (tag instanceof AppInfo) {
// 点击 App 图标
startAppShortcutOrInfoActivity(v, (AppInfo) tag, launcher
);
} else if (tag instanceof LauncherAppWidgetInfo) {
if (v instanceof PendingAppWidgetHostView) {
onClickPendingWidget((PendingAppWidgetHostView) v, launcher);
}
} else if (tag instanceof SearchActionItemInfo) {
onClickSearchAction(launcher, (SearchActionItemInfo) tag);
}
}
---------------------------------------------------
private static void startAppShortcutOrInfoActivity(View v, ItemInfo item, Launcher launcher) {
Intent intent;
if (item instanceof ItemInfoWithIcon
&& (((ItemInfoWithIcon) item).runtimeStatusFlags
& ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE) != 0) {
ItemInfoWithIcon appInfo = (ItemInfoWithIcon) item;
intent = new PackageManagerHelper(launcher)
.getMarketIntent(appInfo.getTargetComponent().getPackageName());
} else {
intent = item.getIntent();
}
if (intent == null) {
throw new IllegalArgumentException("Input must have a valid intent");
}
if (item instanceof WorkspaceItemInfo) {
WorkspaceItemInfo si = (WorkspaceItemInfo) item;
if (si.hasStatusFlag(WorkspaceItemInfo.FLAG_SUPPORTS_WEB_UI)
&& Intent.ACTION_VIEW.equals(intent.getAction())) {
intent = new Intent(intent);
intent.setPackage(null);
}
if ((si.options & WorkspaceItemInfo.FLAG_START_FOR_RESULT) != 0) {
launcher.startActivityForResult(item.getIntent(), 0);
InstanceId instanceId = new InstanceIdSequence().newInstanceId();
launcher.logAppLaunch(launcher.getStatsLogManager(), item, instanceId);
return;
}
}
if (v != null && launcher.supportsAdaptiveIconAnimation(v)) {
// Preload the icon to reduce latency b/w swapping the floating view with the original.
FloatingIconView.fetchIcon(launcher, v, item, true /* isOpening */);
}
// 调用Launcher#startActivitySafely()启动Activity
launcher.startActivitySafely(v, intent, item);
}
}
回答上面的问题,AllAppsRecyclerView在AllAppsContainerView中设置了AllAppsGridAdapter,在 AllAppsGridAdapter#onCreateViewHolder() 方法中为子项itemView设置点击事件 ItemClickHandler.INSTANCE。
1.3 Launcher#startActivitySafely()
下面回到Launcher这个Activity中看一下startActivitySafely()方法,代码如下:
// packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
public class Launcher extends StatefulActivity<LauncherState> implements LauncherExterns,
Callbacks, InvariantDeviceProfile.OnIDPChangeListener, PluginListener<OverlayPlugin>,
LauncherOverlayCallbacks {
@Override
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
if (!hasBeenResumed()) {
addOnResumeCallback(() -> startActivitySafely(v, intent, item));
if (mOnDeferredActivityLaunchCallback != null) {
mOnDeferredActivityLaunchCallback.run();
mOnDeferredActivityLaunchCallback = null;
}
return true;
}
// 调用父类的startActivitySafely()方法
boolean success = super.startActivitySafely(v, intent, item);
if (success && v instanceof BubbleTextView) {
BubbleTextView btv = (BubbleTextView) v;
btv.setStayPressed(true);
addOnResumeCallback(() -> btv.setStayPressed(false));
}
return success;
}
}
------------------------------------------
// 继承关系:Launcher =》StatefulActivity=》BaseDraggingActivity
public abstract class BaseDraggingActivity extends BaseActivity
implements OnColorsChangedListener, DisplayInfoChangeListener {
public boolean startActivitySafely(View v, Intent intent, @Nullable ItemInfo item) {
......
Bundle optsBundle = (v != null) ? getActivityLaunchOptions(v, item).toBundle() : null;
UserHandle user = item == null ? null : item.user;
// Prepare intent
// 添加 FLAG_ACTIVITY_NEW_TASK,即在新的Task中启动 Activity
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (v != null) {
intent.setSourceBounds(Utilities.getViewBounds(v));
}
try {
boolean isShortcut = (item instanceof WorkspaceItemInfo)
&& (item.itemType == Favorites.ITEM_TYPE_SHORTCUT
|| item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
&& !((WorkspaceItemInfo) item).isPromise();
if (isShortcut) {
// 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
// 点击App图标 启动 App
startActivity(intent, optsBundle);
} else {
getSystemService(LauncherApps.class).startMainActivity(
intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
}
if (item != null) {
InstanceId instanceId = new InstanceIdSequence().newInstanceId();
logAppLaunch(getStatsLogManager(), item, instanceId);
}
return true;
} catch (NullPointerException | ActivityNotFoundException | SecurityException e) {
......
}
return false;
}
}
根Activity启动时,添加FLAG_ACTIVITY_NEW_TASK,即在新的任务栈Task中启动Activity,然后调⽤到Activity# startActivity()⽅法,传⼊参数为intent和Bundle。代码如下:
// frameworks/base/core/java/android/app/Activity.java
public class Activity extends ContextThemeWrapper
implements ... {
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
......
if (options != null) {
// 通过startActivityForResult启动Activity
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
// mParent 表示当前Activity的父 Activity,一般情况下mParent为空
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
}
Activity#startActivity()方法调用Activity#startActivityForResult()方法,Activity#startActivity()第二个参数为-1表示Launcher不需要知道根Activity的启动结果。由于mParent=null(mParent表示当前Activity的父Activity,一般情况下mParent为空),所以我们只需要关注mParent=null的情况,此时会调用Instrumentation#execStartActivity() 方法。
1.4 Instrumentation#execStartActivity()
Instrumentation负责调用Activity和Application的生命周期,每个Activity都持有Instrumentation对象的一个引用,但是整个进程只会存在一个Instrumentation对象。跟进去看看Instrumentation#execStartActivity()方法,代码如下:
// frameworks/base/core/java/android/app/Instrumentation.java
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
......
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
// 获取ActivityTaskManagerService的代理对象
int result = ActivityTaskManager.getService()
.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;
}
Instrumentation#execStartActivity()方法会调用ActivityTaskManager#getService()方法来获取ActivityTaskManagerService的代理对象,然后调用这个代理对象的startActivity()方法。
// frameworks/base/core/java/android/app/ActivityTaskManager.java
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
@UnsupportedAppUsage(trackingBug = 129726065)
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
new Singleton<IActivityTaskManager>() {
@Override
protected IActivityTaskManager create() {
// 获取ActivityTaskManagerService的引用
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
// 返回一个代理对象
return IActivityTaskManager.Stub.asInterface(b);
}
};
在Singleton的create()方法中,获取ActivityTaskManagerService的引用,这是一个IBinder类型的引用,且 ActivityTaskManagerService作为服务端处于system_server进程,与当前作为客户端的Launcher进程不在同一个进程。 所以这里方法返回的是IActivityTaskManager.Stub的代理对象,而ActivityTaskManagerService则是对应的实现类,继承了IActivityTaskManager.Stub并实现相应的方法,通过代理对象可以跨进程调用服务端ActivityTaskManagerService的方法。
2.ATMS向AMS发送创建应用进程的过程
system_server进程中startBootstrapServices()方法启动系统引导服务,引导服务中启动了ATM(ActivityTaskManagerService)、AMS 等服务,其中ATMS是Android 10中新增的,本来都是AMS来管理,Google 考虑到AMS职责太多、代码太庞大,所以单独拆出来ATMS用于管理Activity及其容器类,如Task、Stack、Display 等,分担AMS部分职责。
2.1 时序图

2.2 ATMS(ActivityTaskManagerService)
通过上面的分析,启动过程走到了ATMS中,调用ATMS#startActivity()方法,代码如下:
// frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@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) {
// UserHandle.getCallingUserId()方法会获取调用者的UserId
return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
@Override
public int startActivityAsUser(IApplicationThread caller, String callingPackage,
String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
Bundle bOptions, int userId) {
// 继续调用startActivityAsUser
return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
true /*validateIncomingUser*/);
}
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);
// 检查调用者的进程是否隔离,如果isIsolated则抛出SecurityException异常
enforceNotIsolatedCaller("startActivityAsUser");
// 检查调用者权限,ATMS根据传入的UserId来确定调用者的权限
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
// 获取ActivityStarter,然后调用它的execute()执行启动Activity的过程
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)
.execute(); // 执行启动任务
}
// 获取ActivityStartController
ActivityStartController getActivityStartController() {
return mActivityStartController;
}
2.3 ActivityStartController
// frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
/**
* @return A starter to configure and execute starting an activity. It is valid until after
* {@link ActivityStarter#execute} is invoked. At that point, the starter should be
* considered invalid and no longer modified or used.
*/
ActivityStarter obtainStarter(Intent intent, String reason) {
return mFactory.obtain().setIntent(intent).setReason(reason);
}
获取ActivityStarter对象后通过Builder模式设置启动所需的各种参数值,然后执行启动Activity。ActivityStarter是 Android 7.0中增加的,用来加载启动Activity的控制类。
2.4 ActivityStarter
// frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
class ActivityStarter {
@VisibleForTesting
interface Factory {
// Sets the {@link ActivityStartController} to be passed to {@link ActivityStarter}.
void setController(ActivityStartController controller);
// 生成一个准备处理新启动请求的ActivityStarter,ActivityStartController持有这个实例对象
ActivityStarter obtain();
// Recycles a starter for reuse.
void recycle(ActivityStarter starter);
}
-----------------------------------------------------------
// Default implementation of {@link StarterFactory}.
static class DefaultFactory implements Factory {
// 被激活的启动器的最大数
private final int MAX_STARTER_COUNT = 3;
private ActivityStartController mController;
private ActivityTaskManagerService mService;
private ActivityStackSupervisor mSupervisor;
private ActivityStartInterceptor mInterceptor;
private SynchronizedPool<ActivityStarter> mStarterPool =
new SynchronizedPool<>(MAX_STARTER_COUNT);
DefaultFactory(ActivityTaskManagerService service,
ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
mService = service;
mSupervisor = supervisor;
mInterceptor = interceptor;
}
@Override
public void setController(ActivityStartController controller) {
mController = controller;
}
@Override
public ActivityStarter obtain() {
// 直接获取已有的ActivityStarter
ActivityStarter starter = mStarterPool.acquire();
if (starter == null) {
// 如果没有获取到已有的,就新创建一个
starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
}
return starter;
}
@Override
public void recycle(ActivityStarter starter) {
starter.reset(true /* clearRequest*/);
mStarterPool.release(starter);
}
}
-----------------------------------------------------------
/**
* Resolve necessary information according the request parameters provided earlier, and execute
* the request which begin the journey of starting an activity.
* @return The starter result.
*/
int execute() {
try {
int res;
synchronized (mService.mGlobalLock) {
final boolean globalConfigWillChange = mRequest.globalConfig != null
&& mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0;
final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack();
if (stack != null) {
stack.mConfigWillChange = globalConfigWillChange;
}
final long origId = Binder.clearCallingIdentity();
res = resolveToHeavyWeightSwitcherIfNeeded();
if (res != START_SUCCESS) {
return res;
}
// 继续调用executeRequest()方法
res = executeRequest(mRequest);
Binder.restoreCallingIdentity(origId);
if (globalConfigWillChange) {
......
mService.updateConfigurationLocked(mRequest.globalConfig, null, false);
}
// Notify ActivityMetricsLogger that the activity has launched.
// ActivityMetricsLogger will then wait for the windows to be drawn and populate
// WaitResult.
mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,
mLastStartActivityRecord);
return getExternalResult(mRequest.waitResult == null ? res
: waitForResult(res, mLastStartActivityRecord));
}
} finally {
onExecutionComplete();
}
}
-----------------------------------------------------------
private int executeRequest(Request request) {
......
// 创建 ActivityRecord,保存 Activity 的所有信息
final ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
callingPackage, callingFeatureId, intent, resolvedType, aInfo,
mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode,
request.componentSpecified, voiceSession != null, mSupervisor, checkedOptions,
sourceRecord);
mLastStartActivityRecord = r;
......
final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack();
// 继续调用startActivityUnchecked()方法
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
restrictedBgActivity, intentGrants);
......
return mLastStartActivityResult;
}
-----------------------------------------------------------
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
boolean restrictedBgActivity, NeededUriGrants intentGrants) {
int result = START_CANCELED;
try {
mService.deferWindowLayout();
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
}
......
return result;
}
-----------------------------------------------------------
@VisibleForTesting
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
boolean restrictedBgActivity, NeededUriGrants intentGrants) {
......
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTask().topRunningActivityLocked();
if (!mTargetStack.isTopActivityFocusable()
|| (topTaskActivity != null && topTaskActivity.isTaskOverlay()
&& mStartActivity != topTaskActivity)) {
......
mTargetStack.ensureActivitiesVisible(null /* starting */,
0 /* configChanges */, !PRESERVE_WINDOWS);
// Go ahead and tell window manager to execute app transition for this activity
// since the app transition will not be triggered through the resume channel.
mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
} else {
......
// 启动流程交给mRootWindowContainer的resumeFocusedStacksTopActivities()
mRootWindowContainer.resumeFocusedStacksTopActivities(
mTargetStack, mStartActivity, mOptions);
}
}
}
}
-
在上面的第一步中获取ActivityStartController,调用其obtainStarter()方法,通过内部实现的DefaultFactory来获取 ActivityStarter,如果在mStarterPool中没有获取到,则新创建一个。
-
上面介绍了ActivityStarter类是用来加载启动Activity的控制类,在ActivityStarter#execute() 方法中,会继续调用 ActivityStarter#executeRequest() 方法,这里会处理启动Activity的请求,并开始一个Activity 启动的流程。
-
ActivityStarter#executeRequest()方法会进行初步的检查并且确认权限,并且在这里组装对应Activity的ActivityRecord,其包含了对应Activity的所有信息,并储存在任务栈TaskRecord中。在Activity的启动过程中,Activity都是通过ActivityRecord来表示的。然后继续调用ActivityStarter#startActivityUnchecked() 方法,接着 ActivityStarter#startActivityUnchecked()方法会调用ActivityStarter#startActivityInner()方法。
-
在ActivityStarter#startActivityInner()方法中,主要就是处理Activity的启动模式有关的逻辑,并且在ActivityStack中处理对应Activity在任务栈中的相关事宜,包括但不限于将对应的ActivityRecord添加到TaskRecord栈中、将对应的ActivityRecord提到TaskRecord栈中最顶部。
-
最后调用 RootWindowContainer#resumeFocusedStacksTopActivities()方法,将启动流程交给RootWindowContainer处理。
2.5 RootWindowContainer
// frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
boolean resumeFocusedStacksTopActivities(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
......
boolean result = false;
if (targetStack != null && (targetStack.isTopStackInDisplayArea()
|| getTopDisplayFocusedStack() == targetStack)) {
result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
boolean resumedOnDisplay = false;
......
if (!resumedOnDisplay) {
// In cases when there are no valid activities (e.g. device just booted or launcher
// crashed) it's possible that nothing was resumed on a display. Requesting resume
// of top activity in focused stack explicitly will make sure that at least home
// activity is started and resumed, and no recursion occurs.
final ActivityStack focusedStack = display.getFocusedStack();
if (focusedStack != null) {
// focusedStack不为空的时候,调用ActivityStack的方法
result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
} else if (targetStack == null) {
result |= resumeHomeActivity(null /* prev */, "no-focusable-task",
display.getDefaultTaskDisplayArea());
}
}
}
return result;
}
RootWindowContainer是窗口容器(WindowContainer)的根容器,管理所有的窗口容器,设备上所有的窗口(Window)、显示(Display)都是由它来管理的。
RootWindowContainer#resumeFocusedStacksTopActivities()方法会恢复对应任务栈顶部的Activity,方法中会检查一些可见性相关的属性,后转交给ActivityStack#resumeTopActivityUncheckedLocked() 方法来继续启动流程。
2.6 ActivityStack
// frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
@GuardedBy("mService")
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mInResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean result = false;
try {
// Protect against recursion.
mInResumeTopActivity = true;
// 直接调用内部方法
result = resumeTopActivityInnerLocked(prev, options);
// When resuming the top activity, it may be necessary to pause the top activity (for
// example, returning to the lock screen. We suppress the normal pause logic in
// {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the
// end. We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here
// to ensure any necessary pause logic occurs. In the case where the Activity will be
// shown regardless of the lock screen, the call to
// {@link ActivityStackSupervisor#checkReadyForSleepLocked} is skipped.
final ActivityRecord next = topRunningActivity(true /* focusableOnly */);
if (next == null || !next.canTurnScreenOn()) {
checkReadyForSleep();
}
} finally {
mInResumeTopActivity = false;
}
return result;
}
----------------------------------------------------------
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
if (next.attachedToProcess()) {
......
ActivityRecord lastResumedActivity =
lastFocusedStack == null ? null : lastFocusedStack.mResumedActivity;
final ActivityState lastState = next.getState();
next.setState(RESUMED, "resumeTopActivityInnerLocked");
next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,
true /* activityChange */, true /* updateOomAdj */,
true /* addPendingTopUid */);
// From this point on, if something goes wrong there is no way
// to recover the activity.
try {
next.completeResumeLocked();
} catch (Exception e) {
......
mStackSupervisor.startSpecificActivity(next, true, false);
return true;
}
} else {
// Whoops, need to restart this activity!
......
}
return true;
}
ActivityStack是一个管理类,用来管理系统所有Activity的各种状态,其内部维护了TaskRecord的列表,每个TaskRecord又包含了若干个ActivityRecord,每个ActivityRecord对应了一个Activity。这里TaskRecord相当于在启动模式中的“任务栈”,根据启动模式的不同,在启动Activity的时候,会对TaskRecord进行不同的操作。
由于前一步已经将对应Activity的ActivityRecord 添加到了栈顶,所以ActivityStack#resumeTopActivityUncheckedLocked() 方法恢复的就是将启动的栈顶Activity,然后继续调用 ActivityStack#resumeTopActivityInnerLocked()方法来继续启动流程,该方法中做了一系列判断,确保待启动 Activity可见性、预定Activity的切换动画等。后转交给ActivityStackSupervisor#startSpecificActivity()方法来启动栈顶特定的Activity。
2.7 ActivityStackSupervisor
// frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
// 获取即将要启动的 Activity 的所在的应用程序进程已经运行了吗?
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;
// wpc.hasThread() 内部通过判断 IApplicationThread 是否被赋值,如果已赋值,即应用进程已运行
// 启动 Activity 的应用程序进程已经创建运行则走 Activity 的生命周期
// 即普通 Activity 的启动走 realStartActivityLocked() 方法继续 Activity 的创建
if (wpc != null && wpc.hasThread()) {
try {
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
......
}
// If a dead object exception was thrown -- fall through to
// restart the application.
knownToBeDead = true;
}
r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
final boolean isTop = andResume && r.isTopRunningActivity();
// 如果未赋值,即应用进程还不存在,则需要创建应用进程,由于是根 Activity 的启动所以应用进程还未被创建并启动
mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
}
ActivityStackSupervisor是用来辅助ATMS对Activity和Task进行管理的,其中ActivityStackSupervisor是对ActivityStack进行管理的,用ActivityStack对Acitivity进行状态管理。
ActivityStackSupervisor内部管理了mHomeStack、mFocusedStack和mLastFocusedStack三个ActivityStack:
- mHomeStack管理的是Launcher相关的Activity栈,stackId为0。
- mFocusedStack管理的是当前显示在前台Activity的Activity 栈。
- mLastFocusedStack管理的是上一次显示在前台Activity 的Activity栈。
ActivityStackSupervisor#startSpecificActivity()方法中获取WindowProcessController ,通过wpc#hasThread()方法判断应用进程是否已创建并运行中,其内部是通过IApplicationThread是否已经被赋值来判断的,如果已被赋值则表示应用进程已创建且运行中,此时进入判断体内部,走ActivityStackSupervisor#realStartActivityLocked() 方法继续Activity的启动流程,即普通Activity的启动流程。如果未被赋值,则需要创建应用进程,这里由于是根Activity的启动所以应用进程还未被创建并启动。
留个小问题,WindowProcessController#IApplicationThread是何时、在哪里赋值的?(下一篇继续)
网友评论