前言
面试中经常会被问到,让面试者简述一下 Activity 的启动流程,这个问题是考察面试者对源码的理解程度,要征服面试官获得满意的 offer 还是需要一步步深入去探索一下源码,梳理启动流程并形成自己的总结,而不要死记硬背。 回答这个问题,可以根据 Activity 的启动时机,从两个方面入手:
- 根 Activity 的启动流程: 又叫应用程序启动流程,即点击桌面上某一个应用图标到应用第一个 Activity 展示出来的流程。
- 普通 Activity 的启动流程: 即应用内启动一个 Activity 到展示出来的流程。
由于两种启动流程是有重叠的,根 Activity 的启动流程更复杂,所以下面我们基于 Android R(11.0) 重点分析根 Activity 的启动流程,而普通 Activity 的启动流程在涉及的地方会稍微提一下。
应用的启动流程大致分为下面五个阶段: ????一、应用启动进程 Launcher 调用 ATMS 系统进程的过程 ????二、ATMS 向 AMS 发送创建应用进程的过程 ????三、AMS 向 Zygote 进程发送创建应用进程 ActivityThread 的过程 ????四、Zygote 进程接收请求 fork 并启动应用进程 ActivityThread 的过程 ????五、应用进程 ActivityThread 启动 Activity 的过程
一、应用启动进程 Launcher 调用 ATMS 系统进程的过程
Launcher 是一个用于显示所有应用程序的一个系统级别的应用程序,也就是我们常说的桌面,通过 PackageManagerService 来获取已安装的所有应用程序信息。实际上就是一个 Activity,由 AMS(ActivityManagerService)来管理进程调度与启动,AMS 是 Android 中最核心的系统服务,几乎所有的应用都需要与 AMS 通信。
根 Activity 的启动流程其实就是点击 Launcher 中某一个应用图标到应用第一个 Activity 展示出来的流程,当系统开机后,Launcher 也会被 AMS 启动,然后将已经安装的应用程序图标显示到桌面上,所以当我们点击一个应用图标其实就是相当于点击 Activity 中的一个 Button,其相应事件就是 Launcher 进程请求 ATMS 来启动该应用程序。
1. 时序图

2. Launcher 桌面的 App 图标入口
从源码看一下 Launcher 桌面是不是如我们所说的是一个 Activity,源码如下:
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);
......
inflateRootView(R.layout.launcher);
}
}
public abstract class StatefulActivity<STATE_TYPE extends BaseState<STATE_TYPE>>
extends BaseDraggingActivity {}
@SuppressWarnings("NewApi")
public abstract class BaseDraggingActivity extends BaseActivity
implements OnColorsChangedListener, DisplayInfoChangeListener {}
public abstract class BaseActivity extends Activity implements ActivityContext {}
分析1 – 正如我们所说,Launcher 就是一个 Activity,加载的布局为 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">
<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>
<?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">
<include
layout="@layout/all_apps_rv_layout"
android:visibility="gone" />
</com.android.launcher3.allapps.LauncherAllAppsContainerView>
<?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 里面,看一下代码:
public class AllAppsContainerView extends SpringRelativeLayout implements DragSource,
Insettable, OnDeviceProfileChangeListener, OnActivePageChangedListener,
ScrimView.ScrimDrawingController {
protected void rebindAdapters(boolean force) {
......
if (mUsingTabs) {
......
} else {
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 = 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);
recyclerView.setAdapter(adapter);
}
}
}
源码中在 AllAppsContainerView 中为 AllAppsRecyclerView 设置了 AllAppsGridAdapter,然后在 AllAppsGridAdapter # onCreateViewHolder() 方法中为子项 itemView 设置点击事件 ItemClickHandler.INSTANCE,点击事件由 launcher.getItemOnClickListener() 方法获取。看一下 ItemClickHandler 是怎么处理点击事件的,代码如下:
public class ItemClickHandler {
private static final String TAG = ItemClickHandler.class.getSimpleName();
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) {
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)) {
FloatingIconView.fetchIcon(launcher, v, item, true );
}
launcher.startActivitySafely(v, intent, item);
}
}
回答上面的问题,AllAppsRecyclerView 在 AllAppsContainerView 中设置了 AllAppsGridAdapter,在 AllAppsGridAdapter # onCreateViewHolder() 方法中为子项 itemView 设置点击事件 ItemClickHandler.INSTANCE。
3. Launcher # startActivitySafely() 方法
下面回到 Launcher 这个 Activity 中看一下 startActivitySafely() 方法,代码如下:
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;
}
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;
}
}
@SuppressWarnings("NewApi")
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;
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) {
startShortcutIntentSafely(intent, optsBundle, item);
} else if (user == null || user.equals(Process.myUserHandle())) {
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。代码如下:
public class Activity extends ContextThemeWrapper
implements ... {
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
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() 方法。
4. Instrumentation # execStartActivity() 方法
Instrumentation 负责调用 Activity 和 Application 的生命周期,每个 Activity 都持有 Instrumentation 对象的一个引用,但是整个进程只会存在一个 Instrumentation 对象。跟进去看看 Instrumentation # execStartActivity () 方法,代码如下:
@UnsupportedAppUsage
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
......
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
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() 方法。
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
@UnsupportedAppUsage(trackingBug = 129726065)
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
new Singleton<IActivityTaskManager>() {
@Override
protected IActivityTaskManager create() {
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 的方法。
二、ATMS 向 AMS 发送创建应用进程的过程
system_server 进程中 startBootstrapServices() 方法启动系统引导服务,引导服务中启动了 ATMS(ActivityTaskManagerServici)、AMS 等服务,其中 ATMS 是 Android 10 中新增的,本来都是 AMS 来管理,Google 考虑到 AMS 职责太多、代码太庞大,所以单独拆出来 ATMS 用于管理 Activity。
1. 时序图

2. ATMS(ActivityTaskManagerService)
通过上面的分析,启动过程走到了 ATMS 中,调用 ATMS # startActivity() 方法,代码如下:
@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());
}
@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) {
return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
true );
}
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");
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 getActivityStartController() {
return mActivityStartController;
}
3. ActivityStartController
ActivityStarter obtainStarter(Intent intent, String reason) {
return mFactory.obtain().setIntent(intent).setReason(reason);
}
获取 ActivityStarter 对象用来配置并执行启动 Activity。ActivityStarter 是 Android 7.0 中增加的,用来加载启动 Activity 的控制类。
4. ActivityStarter
class ActivityStarter {
@VisibleForTesting
interface Factory {
void setController(ActivityStartController controller);
ActivityStarter obtain();
void recycle(ActivityStarter starter);
}
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 starter = mStarterPool.acquire();
if (starter == null) {
starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
}
return starter;
}
@Override
public void recycle(ActivityStarter starter) {
starter.reset(true );
mStarterPool.release(starter);
}
}
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;
}
res = executeRequest(mRequest);
Binder.restoreCallingIdentity(origId);
if (globalConfigWillChange) {
......
mService.updateConfigurationLocked(mRequest.globalConfig, null, false);
}
mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,
mLastStartActivityRecord);
return getExternalResult(mRequest.waitResult == null ? res
: waitForResult(res, mLastStartActivityRecord));
}
} finally {
onExecutionComplete();
}
}
private int executeRequest(Request request) {
......
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();
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true , 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 ,
0 , !PRESERVE_WINDOWS);
mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
} else {
......
mRootWindowContainer.resumeFocusedStacksTopActivities(
mTargetStack, mStartActivity, mOptions);
}
}
}
}
在上面的第一步中获取 ActivityStartController,调用其 obtainStarter() 方法,通过内部实现的 DefaultFactory 来获取 ActivityStarter,如果在 mStarterPool 中没有获取到,则新创建一个。
获取到 ActivityStarter 后,通过 Builder 模式设置启动所需的各种参数值,然后执行 ActivityStarter # execute() 方法。
5. RootWindowContainer
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) {
final ActivityStack focusedStack = display.getFocusedStack();
if (focusedStack != null) {
result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
} else if (targetStack == null) {
result |= resumeHomeActivity(null , "no-focusable-task",
display.getDefaultTaskDisplayArea());
}
}
}
return result;
}
6. ActivityStack
@GuardedBy("mService")
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mInResumeTopActivity) {
return false;
}
boolean result = false;
try {
mInResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, options);
final ActivityRecord next = topRunningActivity(true );
if (next == null || !next.canTurnScreenOn()) {
checkReadyForSleep();
}
} finally {
mInResumeTopActivity = false;
}
return result;
}
@GuardedBy("mService")
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 ,
true , true ,
true );
try {
next.completeResumeLocked();
} catch (Exception e) {
......
mStackSupervisor.startSpecificActivity(next, true, false);
return true;
}
} else {
......
}
return true;
}
ActivityStack 是一个管理类,用来管理系统所有 Activity 的各种状态,其内部维护了 TaskRecord 的列表,因此从 Activity 任务栈这一角度来说,ActivityStack 也可以理解为 Activity 堆栈,它由 ActivityStackSupervisor 来进行管理。
7. ActivityStackSupervisor
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;
if (wpc != null && wpc.hasThread()) {
try {
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
......
}
knownToBeDead = true;
}
r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
final boolean isTop = andResume && r.isTopRunningActivity();
mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
}
ActivityStackSupervisor 是用来辅助 ActivityManagerService 对 Activity 和 Task 的管理的。其中用 ActivityStackSupervisor 类来进行对 ActivityStack 的操作,用 ActivityStack 对 Acitivity 进行操作。
ActivityStackSupervisor 内部管理了 mHomeStack、mFocusedStack 和 mLastFocusedStack 三个 ActivityStack:
- mHomeStack 管理的是 Launcher 相关的 Activity 栈,stackId为0。
- mFocusedStack 管理的是当前显示在前台 Activity 的 Activity 栈。
- mLastFocusedStack 管理的是上一次显示在前台 Activity 的 Activity 栈。
三、AMS 向 Zygote 进程发送创建应用进程 ActivityThread 的过程
1. ActivityTaskManagerService
void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
String hostingType) {
try {
if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "dispatchingStartProcess:"
+ activity.processName);
}
final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
isTop, hostingType, activity.intent.getComponent());
mH.sendMessage(m);
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
方法中需要发送 Handler 消息来启动进程,在获取 Message 消息对象时跟我们平时的使用方式不太一样,看到这有点懵哈! 这里是用到 PooledLambda # obtainMessage() 函数,代码如下:
static <A, B, C, D, E, F> Message obtainMessage(
HexConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F> function,
A arg1, B arg2, C arg3, D arg4, E arg5, F arg6) {
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
function, 6, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, null, null,
null, null, null);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
可以看到这是一个静态函数,可以在接口外部直接被调用,这是 Java 1.8 的新特性,被 static 或 default 修饰的接口方法可以有默认实现,感兴趣的童鞋可以自行查阅哈。接口里面使用了经典的 lambda 定义方式,这个泛型的定义巧妙的将我们的函数以及需要传入的参数类型连接起来,第一个传入的 lambda 接口跟后面的参数类型紧密有关,调用这个函数的时候直接将需要传入的参数一并传入。这里需要提到的是 lambda 里面的中间接口是一种隐藏式的存在,我们在调用的过程中可以直接匿名忽略掉,上面的调用实例就是如此,直接使用了 ::符号 直接链接到目标函数 startProcess()。
所以语法含义是调用 ActivityManagerInternal 类的 startProcess() 方法,后面的那些变量就是传递到 startProcess() 方法的入参。具体的再说就偏离主题了,感兴趣的可以自行查阅,简要说明就是这里通过 acquire() 函数获取到一个 PooledRunnable 实例,又通过它的 recycleOnUse() 函数得到一个 PooledLambdaImpl(实现了 PooledLambda 接口)的实例,所以当我们后续再调用 sendMessage() 的时候这个 PooledRunnable 的 run() 方法会得到执行,也即 ActivityManagerInternal # startProcess() 方法。
ActivityManagerInternal 是一个抽象类,它是 Activity 管理本地服务接口的,它的实现为 AMS 的内部类 LocalService,在 AMS 启动的过程,通过 LocalServices # addService() 注册到 LocalServices,此类的使用方式与 ServiceManager 相似,不同之处在于,此处注册的服务不是 Binder 对象,并且只能在同一进程(system_server进程)中使用。也就是说 ActivityManagerInternal 实现类 LocalService 是 system_server 进程的本地服务 Service,通过本地服务注册到 LocalServices 中,而 AMS 也是运行在 system_server 进程,因此可以直接使用 LocalService。
LocalServices 可以理解为是一个公开缓存池,内部使用 ArrayMap 来存储本地服务对象。system_server 进程中每个服务都可以通过 LocalServices # addService() 注册到 LocalServices 中,需要使用存储的 LocalService 时通过 LocalServices # getService() 获取注册的本地服务。
2. ActivityManagerService
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
@VisibleForTesting
public final class LocalService extends ActivityManagerInternal {
......
@Override
public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
boolean isTop, String hostingType, ComponentName hostingName) {
try {
if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startProcess:"
+ processName);
}
synchronized (ActivityManagerService.this) {
startProcessLocked(processName, info, knownToBeDead, 0 ,
new HostingRecord(hostingType, hostingName, isTop),
ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false ,
false , true );
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
......
}
@GuardedBy("this")
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 ,
keepIfLarge, null , null ,
null , null );
}
}
AMS 通过 ProcessRecord 实例记录管理每个进程的信息。
3. ProcessList
@GuardedBy("mService")
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid,
boolean keepIfLarge, String abiOverride, String entryPoint, String[] entryPointArgs,
Runnable crashHandler) {
......
ProcessRecord app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
checkSlow(startTime, "startProcess: stepping in to startProcess");
final boolean success =
startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride);
checkSlow(startTime, "startProcess: done starting proc!");
return success ? app : null;
}
@GuardedBy("mService")
final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
int zygotePolicyFlags, String abiOverride) {
return startProcessLocked(app, hostingRecord, zygotePolicyFlags,
false , false ,
false , abiOverride);
}
@GuardedBy("mService")
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks,
boolean mountExtStorageFull, String abiOverride) {
......
try {
app.gids = gids;
app.setRequiredAbi(requiredAbi);
app.instructionSet = instructionSet;
final String entryPoint = "android.app.ActivityThread";
return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,
instructionSet, invokeWith, startTime);
}
......
}
@GuardedBy("mService")
boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
long startTime) {
......
if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
......
} else {
try {
final Process.ProcessStartResult startResult = startProcess(hostingRecord,
entryPoint, app,
uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
requiredAbi, instructionSet, invokeWith, startTime);
handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
startSeq, false);
}
......
return app.pid > 0;
}
}
private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags,
int mountExternal, String seInfo, String requiredAbi, String instructionSet,
String invokeWith, long startTime) {
try {
......
final Process.ProcessStartResult startResult;
if (hostingRecord.usesWebviewZygote()) {
startResult = startWebView(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, null, app.info.packageName, app.mDisabledCompatChanges,
new String[]{PROC_START_SEQ_IDENT + app.startSeq});
} else if (hostingRecord.usesAppZygote()) {
final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
startResult = appZygote.getProcess().start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, null, app.info.packageName,
ZYGOTE_POLICY_FLAG_EMPTY, isTopApp,
app.mDisabledCompatChanges, pkgDataInfoMap, whitelistedAppDataInfoMap,
false, false,
new String[]{PROC_START_SEQ_IDENT + app.startSeq});
} else {
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,
isTopApp, app.mDisabledCompatChanges, pkgDataInfoMap,
whitelistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
new String[]{PROC_START_SEQ_IDENT + app.startSeq});
}
return startResult;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
经过调用 4 个 startProcessLocked() 方法后,调用到了 startProcess() 方法,然后在 startProcess() 方法里做了一个判断,根据不同的参数调用不同的方法启动进程,这里跟进 Process # start() 继续追踪源码。
4. Process
public static final ZygoteProcess ZYGOTE_PROCESS = new ZygoteProcess();
public static ProcessStartResult start(@NonNull final String processClass,
@Nullable final String niceName,
int uid, int gid, @Nullable int[] gids,
int runtimeFlags,
int mountExternal,
int targetSdkVersion,
@Nullable String seInfo,
@NonNull String abi,
@Nullable String instructionSet,
@Nullable String appDataDir,
@Nullable String invokeWith,
@Nullable String packageName,
int zygotePolicyFlags,
boolean isTopApp,
@Nullable long[] disabledCompatChanges,
@Nullable Map<String, Pair<String, Long>>
pkgDataInfoMap,
@Nullable Map<String, Pair<String, Long>>
whitelistedDataInfoMap,
boolean bindMountAppsData,
boolean bindMountAppStorageDirs,
@Nullable String[] zygoteArgs) {
return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, packageName,
zygotePolicyFlags, isTopApp, disabledCompatChanges,
pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,
bindMountAppStorageDirs, zygoteArgs);
}
5. ZygoteProcess
public final Process.ProcessStartResult start(@NonNull final String processClass,
final String niceName,
int uid, int gid, @Nullable int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
@Nullable String seInfo,
@NonNull String abi,
@Nullable String instructionSet,
@Nullable String appDataDir,
@Nullable String invokeWith,
@Nullable String packageName,
int zygotePolicyFlags,
boolean isTopApp,
@Nullable long[] disabledCompatChanges,
@Nullable Map<String, Pair<String, Long>>
pkgDataInfoMap,
@Nullable Map<String, Pair<String, Long>>
whitelistedDataInfoMap,
boolean bindMountAppsData,
boolean bindMountAppStorageDirs,
@Nullable String[] zygoteArgs) {
if (fetchUsapPoolEnabledPropWithMinInterval()) {
informZygotesOfUsapPoolStatus();
}
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, false,
packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges,
pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,
bindMountAppStorageDirs, zygoteArgs);
}
......
}
private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,
@Nullable final String niceName,
final int uid, final int gid,
@Nullable final int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
@Nullable String seInfo,
@NonNull String abi,
@Nullable String instructionSet,
@Nullable String appDataDir,
@Nullable String invokeWith,
boolean startChildZygote,
@Nullable String packageName,
int zygotePolicyFlags,
boolean isTopApp,
@Nullable long[] disabledCompatChanges,
@Nullable Map<String, Pair<String, Long>>
pkgDataInfoMap,
@Nullable Map<String, Pair<String, Long>>
whitelistedDataInfoMap,
boolean bindMountAppsData,
boolean bindMountAppStorageDirs,
@Nullable String[] extraArgs)
throws ZygoteStartFailedEx {
ArrayList<String> argsForZygote = new ArrayList<>();
......
argsForZygote.add(processClass);
......
synchronized(mLock) {
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
zygotePolicyFlags, argsForZygote);
}
}
@GuardedBy("mLock")
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
try {
attemptConnectionToPrimaryZygote();
if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}
if (mZygoteSecondarySocketAddress != null) {
attemptConnectionToSecondaryZygote();
if (secondaryZygoteState.matches(abi)) {
return secondaryZygoteState;
}
}
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to zygote", ioe);
}
throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
}
private static class ZygoteState implements AutoCloseable {
......
static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress,
@Nullable LocalSocketAddress usapSocketAddress)
throws IOException {
DataInputStream zygoteInputStream;
BufferedWriter zygoteOutputWriter;
final LocalSocket zygoteSessionSocket = new LocalSocket();
if (zygoteSocketAddress == null) {
throw new IllegalArgumentException("zygoteSocketAddress can't be null");
}
try {
zygoteSessionSocket.connect(zygoteSocketAddress);
zygoteInputStream = new DataInputStream(zygoteSessionSocket.getInputStream());
zygoteOutputWriter =
new BufferedWriter(
new OutputStreamWriter(zygoteSessionSocket.getOutputStream()),
Zygote.SOCKET_BUFFER_SIZE);
} catch (IOException ex) {
try {
zygoteSessionSocket.close();
} catch (IOException ignore) { }
throw ex;
}
return new ZygoteState(zygoteSocketAddress, usapSocketAddress,
zygoteSessionSocket, zygoteInputStream, zygoteOutputWriter,
getAbiList(zygoteOutputWriter, zygoteInputStream));
}
}
@GuardedBy("mLock")
private Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList<String> args)
throws ZygoteStartFailedEx {
......
if (shouldAttemptUsapLaunch(zygotePolicyFlags, args)) {
try {
return attemptUsapSendArgsAndGetResult(zygoteState, msgStr);
} catch (IOException ex) {
Log.e(LOG_TAG, "IO Exception while communicating with USAP pool - "
+ ex.getMessage());
}
}
return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
}
private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
try {
final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
zygoteWriter.write(msgStr);
zygoteWriter.flush();
Process.ProcessStartResult result = new Process.ProcessStartResult();
result.pid = zygoteInputStream.readInt();
result.usingWrapper = zygoteInputStream.readBoolean();
if (result.pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}
return result;
} catch (IOException ex) {
zygoteState.close();
Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
+ ex.toString());
throw new ZygoteStartFailedEx(ex);
}
}
ZygoteProcess # attemptZygoteSendArgsAndGetResult() 方法中使用 BufferedWriter 和 DataInputStream 来进行数据的传输与读取,这两个实例对象是在 ZygoteState.connect() 方法创建包含给定 Zygote socket 地址的 Socket 连接时创建的,所以在进行 Socket 通信时可以用它们进行数据流传输与读取操作。system_server 进程通过 BufferedWriter 将参数写给 Zygote 进程的 socket 的 server 端,然后阻塞等待 Zygote 进程的 socket 返回 pid 和 usingWrapper 后封装到 ProcessStartResult。
四、Zygote 进程接收请求 fork 并启动应用进程 ActivityThread 的过程
1. Zygote 进程启动、解析 Socket 传入的参数
Android 系统底层是基于 Linux 的,和 Linux 一样,init 进程是 Linux 系统用户进程的第一个进程,它是由 Linux 内核(kenerl)启动的,用来启动属性服务(类似Windows中的注册表),启动进程。其它所有的用户进程都是 init 进程的子进程,我们接下来分析的 Zygote 进程也是由 init 进程而创建的,Zygote 如何启动这里暂不讨论,Zygote 启动之后会调用 ZygoteInit.main() 方法,所以我们先从 main() 方法来看 socket 创建和消息读取。代码如下:
public static void main(String argv[]) {
ZygoteServer zygoteServer = null;
......
Runnable caller;
try {
......
boolean startSystemServer = false;
String zygoteSocketName = "zygote";
String abiList = null;
boolean enableLazyPreload = false;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
......
zygoteServer = new ZygoteServer(isPrimaryZygote);
......
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
if (zygoteServer != null) {
zygoteServer.closeServerSocket();
}
}
if (caller != null) {
caller.run();
}
}
ZygoteServer 的 runSelectLoop() 方法,一般我们看到 loop 就知道这是一个循环,当需要创建新的进程的消息到来的时候,子进程会退出循环往下执行,而父进程则继续循环。
2. ZygoteServer 开启 Loop 循环监听 Socket
ZygoteServer(boolean isPrimaryZygote) {
mUsapPoolEventFD = Zygote.getUsapPoolEventFD();
if (isPrimaryZygote) {
mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME);
mUsapPoolSocket =
Zygote.createManagedSocketFromInitSocket(
Zygote.USAP_POOL_PRIMARY_SOCKET_NAME);
} else {
mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.SECONDARY_SOCKET_NAME);
mUsapPoolSocket =
Zygote.createManagedSocketFromInitSocket(
Zygote.USAP_POOL_SECONDARY_SOCKET_NAME);
}
mUsapPoolSupported = true;
fetchUsapPoolPolicyProps();
}
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> socketFDs = new ArrayList<>();
ArrayList<ZygoteConnection> peers = new ArrayList<>();
socketFDs.add(mZygoteSocket.getFileDescriptor());
peers.add(null);
mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;
while (true) {
fetchUsapPoolPolicyPropsWithMinInterval();
mUsapPoolRefillAction = UsapPoolRefillAction.NONE;
int[] usapPipeFDs = null;
StructPollfd[] pollFDs;
if (mUsapPoolEnabled) {
usapPipeFDs = Zygote.getUsapPipeFDs();
pollFDs = new StructPollfd[socketFDs.size() + 1 + usapPipeFDs.length];
} else {
pollFDs = new StructPollfd[socketFDs.size()];
}
int pollIndex = 0;
......
int pollTimeoutMs;
if (mUsapPoolRefillTriggerTimestamp == INVALID_TIMESTAMP) {
pollTimeoutMs = -1;
} else {
long elapsedTimeMs = System.currentTimeMillis() - mUsapPoolRefillTriggerTimestamp;
if (elapsedTimeMs >= mUsapPoolRefillDelayMs) {
pollTimeoutMs = -1;
} else if (elapsedTimeMs <= 0) {
pollTimeoutMs = mUsapPoolRefillDelayMs;
} else {
pollTimeoutMs = (int) (mUsapPoolRefillDelayMs - elapsedTimeMs);
}
}
int pollReturnValue;
try {
pollReturnValue = Os.poll(pollFDs, pollTimeoutMs);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
if (pollReturnValue == 0) {
mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;
mUsapPoolRefillAction = UsapPoolRefillAction.DELAYED;
} else {
boolean usapPoolFDRead = false;
while (--pollIndex >= 0) {
if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
continue;
}
if (pollIndex == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
socketFDs.add(newPeer.getFileDescriptor());
} else if (pollIndex < usapPoolEventFDIndex) {
try {
ZygoteConnection connection = peers.get(pollIndex);
final Runnable command = connection.processOneCommand(this);
if (mIsForkChild) {
......
return command;
} else {
if (connection.isClosedByPeer()) {
connection.closeSocket();
peers.remove(pollIndex);
socketFDs.remove(pollIndex);
}
}
} catch (Exception e) {
......
} finally {
......
mIsForkChild = false;
}
}
}
......
}
......
}
}
runSelectLoop() 方法中获取 zygoteSendArgsAndGetResult() 方法中传输过来的应用进程的启动参数等,即和 Zygote 进程建立起连接。
- 没有连接时就阻塞在那里,当有连接到来时唤醒。
- pollIndex==0 时请求和 Zygote 建立 socket 连接,调用 acceptCommandPeer() 方法创建 ZygoteConnection 对象并调用mZygoteSocket.accept() 建立连接,再添加到 peers 列表中。
- pollIndex > 0 时表示连接已建立,建立连接后,调用 ZygoteConnection # processOneCommand() 方法来接收客户端传输过来的应用进程的启动参数,并执行进程创建工作。
3. ZygoteConnection
Runnable processOneCommand(ZygoteServer zygoteServer) {
String[] args;
try {
args = Zygote.readArgumentList(mSocketReader);
} catch (IOException ex) {
throw new IllegalStateException("IOException on command socket", ex);
}
......
int pid;
FileDescriptor childPipeFd = null;
FileDescriptor serverPipeFd = null;
ZygoteArguments parsedArgs = new ZygoteArguments(args);
......
int[][] rlimits = null;
if (parsedArgs.mRLimits != null) {
rlimits = parsedArgs.mRLimits.toArray(Zygote.INT_ARRAY_2D);
}
int[] fdsToIgnore = null;
if (parsedArgs.mInvokeWith != null) {
try {
FileDescriptor[] pipeFds = Os.pipe2(O_CLOEXEC);
childPipeFd = pipeFds[1];
serverPipeFd = pipeFds[0];
Os.fcntlInt(childPipeFd, F_SETFD, 0);
fdsToIgnore = new int[]{childPipeFd.getInt$(), serverPipeFd.getInt$()};
} catch (ErrnoException errnoEx) {
throw new IllegalStateException("Unable to set up pipe for invoke-with", errnoEx);
}
}
int [] fdsToClose = { -1, -1 };
FileDescriptor fd = mSocket.getFileDescriptor();
if (fd != null) {
fdsToClose[0] = fd.getInt$();
}
fd = zygoteServer.getZygoteSocketFileDescriptor();
if (fd != null) {
fdsToClose[1] = fd.getInt$();
}
pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mIsTopApp,
parsedArgs.mPkgDataInfoList, parsedArgs.mWhitelistedDataInfoList,
parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs);
try {
if (pid == 0) {
zygoteServer.setForkChild();
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
return handleChildProc(parsedArgs, childPipeFd, parsedArgs.mStartChildZygote);
} else {
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
handleParentProc(pid, serverPipeFd);
return null;
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}
该方法主要作用如下:
- 读取 system_server 端 socket 写入的数据,并将存入字符串数组的数据封装成 ZygoteArguments 格式。
- 调用 Zygote # forkAndSpecialize() 方法来 fork 子进程,并返回 pid,这里的 pid 并非是进程 id,而是返回结果值,0 表示创建成功,-1 则失败。
- 子进程创建成功后进入子进程执行。
4. Zygote 创建子进程(native 层创建)
static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
boolean isTopApp, String[] pkgDataInfoList, String[] whitelistedDataInfoList,
boolean bindMountAppDataDirs, boolean bindMountAppStorageDirs) {
ZygoteHooks.preFork();
int pid = nativeForkAndSpecialize(
uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
fdsToIgnore, startChildZygote, instructionSet, appDataDir, isTopApp,
pkgDataInfoList, whitelistedDataInfoList, bindMountAppDataDirs,
bindMountAppStorageDirs);
if (pid == 0) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
if (gids != null && gids.length > 0) {
NetworkUtils.setAllowNetworkingForProcess(containsInetGid(gids));
}
}
Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
ZygoteHooks.postForkCommon();
return pid;
}
方法中调用 native 层的 nativeForkAndSpecialize() 方法创建进程,然后返回进程的 pid(父进程中,返回新建的子进程的 pid,子进程中,则返回 0,出现错误时返回负数),具体 native 层的源码就不跟了,大致看了一下过程:
- 调用 Linux 的 fork() 方法创建进程,设置进程的主线程的 name,如果是 null 或者 system_server,则为 system_server。
- 调用 CallStaticVoidMethod() 方法返回 Zygote # callPostForkChildHooks() 方法处理 fork 子线程之后的 gc/线程池管理等操作。
5. ZygoteConnection # handleChildProc() 方法
private Runnable handleChildProc(ZygoteArguments parsedArgs,
FileDescriptor pipeFd, boolean isZygote) {
closeSocket();
Zygote.setAppProcessName(parsedArgs, TAG);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
if (parsedArgs.mInvokeWith != null) {
WrapperInit.execApplication(parsedArgs.mInvokeWith,
parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
VMRuntime.getCurrentInstructionSet(),
pipeFd, parsedArgs.mRemainingArgs);
throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
} else {
if (!isZygote) {
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mDisabledCompatChanges,
parsedArgs.mRemainingArgs, null );
} else {
return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null );
}
}
}
该方法就是进入子进程执行不同的初始化操作,因为已经 fork() 成功,关闭 socket 连接等释放资源,设置应用进程的 name,最后调用 ZygoteInit # zygoteInit() 方法重新初始化 Zygote。
6. ZygoteInit # zygoteInit() 方法
public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
......
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
classLoader);
}
7. RuntimeInit # applicationInit() 方法
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
nativeSetExitWithoutCleanup(true);
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
VMRuntime.getRuntime().setDisabledCompatChanges(disabledCompatChanges);
final Arguments args = new Arguments(argv);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className, ex);
}
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException("Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException("Problem getting static main on " + className, ex);
}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException("Main method is not public and static on " + className);
}
return new MethodAndArgsCaller(m, argv);
}
applicationInit() 方法中首先做了一个 System.exit() 的保护,防止退出进程时发生 crash,设置 targetSDKVersion 等参数,最后调用 findStaticMain() 方法去加载 ActivityThread 类以及方法。
findStaticMain() 方法中通过 ClassLoader 加载获取目标类 ActivityThread,后获取其静态 main 方法,然后封装成了 MethodAndArgsCaller 对象返回,MethodAndArgsCaller 实现了 Runnable 接口。即返回给本小节第一部分的 ZygoteInit.main() 中的 caller,如果 caller!=null 会调用这个 Runnable 的 run() 方法。
8. RuntimeInit # MethodAndArgsCaller
static class MethodAndArgsCaller implements Runnable {
private final Method mMethod;
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
......
}
}
}
MethodAndArgsCaller # run() 方法中使用了 invoke 反射调用,至此 ActivityThread 的 main() 方法得以执行,应用进程也就成功启动 ActivityThread。
9. 小结
Zygote 进程启动流程:
- init 进程为用户空间(相对于内核空间)的第一个进程,根据 init.rc 启动 Zygote 进程。
- Zygote 进程启动步骤:创建虚拟机、注册JNI、执行 ZygoteInit # main() 方法。
- Zygote 进程启动 system_server 进程(Zygote 启动的第一个进程),这个本小节没有具体分析。
- Zygote 创建 socket 连接通道,阻塞并等待新建进程的指令到来,通过 fork 新建用户进程。
- Zygote 新加了一个优化进程创建的机制,UsapPool - 池化机制,我跟了一下源码,是预先缓存了几个进程。
五、应用进程 ActivityThread 启动 Activity 的过程
ActivityThread 类是应用初始化类,它的 main() 方法是应用的入口方法,它也是我们说的“主线程”,但是 ActivityThread 本身不是一个线程,之所以称它为“主线程”,是因为它运行在主线程中。所以说 ActivityThread 是主线程的一部分,但不并能代表主线程。
- ActivityThread 负责创建 Application 对象以及管理其生命周期方法调用。
- ActivityThread 管理着四大组件的生命周期方法调用。
1. ActivityThread 入口方法
public final class ActivityThread extends ClientTransactionHandler {
final ApplicationThread mAppThread = new ApplicationThread();
final H mH = new H();
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
......
initializeMainlineModules();
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
......
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
......
} else {
android.ddm.DdmHandleAppName.setAppName("system_process",
UserHandle.myUserId());
try {
mInstrumentation = new Instrumentation();
mInstrumentation.basicInit(this);
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
......
}
}
ActivityThread # attach() 方法中,使用 Binder 通信跨进程调用到 system_server 进程中 AMS 的 attachApplication() 方法,并将 ApplicationThread 作为参数传递过去。
2. AMS 绑定 ApplicationThread
public ActivityTaskManagerInternal mAtmInternal;
public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) {
......
mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
......
}
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
if (thread == null) {
throw new SecurityException("Invalid application interface");
}
synchronized (this) {
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
Binder.restoreCallingIdentity(origId);
}
}
@GuardedBy("this")
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
ProcessRecord app;
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
......
}
......
if (normalMode) {
try {
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
......
}
ActivityTaskManagerInternal 是一个抽象类,实现类是 ATMS 的内部类 LocalService,在 ATMS 启动的时候,通过 LocalServices # addService() 注册到 LocalServices 中。在AMS 的构造方法中通过 LocalServices # getService() 方法获取到注册的本地服务。
3. ATMS 绑定 ApplicationThread
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
final class LocalService extends ActivityTaskManagerInternal {
......
@HotPath(caller = HotPath.PROCESS_CHANGE)
@Override
public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
synchronized (mGlobalLockWithoutBoost) {
if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "attachApplication:" + wpc.mName);
}
try {
return mRootWindowContainer.attachApplication(wpc);
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
}
......
}
}
4. RootWindowContainer 绑定 ApplicationThread
boolean attachApplication(WindowProcessController app) throws RemoteException {
final String processName = app.mName;
boolean didSomething = false;
for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
final DisplayContent display = getChildAt(displayNdx);
final ActivityStack stack = display.getFocusedStack();
if (stack == null) {
continue;
}
mTmpRemoteException = null;
mTmpBoolean = false;
final PooledFunction c = PooledLambda.obtainFunction(
RootWindowContainer::startActivityForAttachedApplicationIfNeeded, this,
PooledLambda.__(ActivityRecord.class), app, stack.topRunningActivity());
stack.forAllActivities(c);
c.recycle();
if (mTmpRemoteException != null) {
throw mTmpRemoteException;
}
didSomething |= mTmpBoolean;
}
if (!didSomething) {
ensureActivitiesVisible(null, 0, false );
}
return didSomething;
}
private boolean startActivityForAttachedApplicationIfNeeded(ActivityRecord r,
WindowProcessController app, ActivityRecord top) {
if (r.finishing || !r.okToShowLocked() || !r.visibleIgnoringKeyguard || r.app != null
|| app.mUid != r.info.applicationInfo.uid || !app.mName.equals(r.processName)) {
return false;
}
try {
if (mStackSupervisor.realStartActivityLocked(r, app, top == r ,
true )) {
mTmpBoolean = true;
}
} catch (RemoteException e) {
.....
return true;
}
return false;
}
attachApplication() 方法中,如何调用到 startActivityForAttachedApplicationIfNeeded() 方法?可以参考上面第三部分第一小节的解析。
5. 获取 ClientTransaction、设置 LifecycleStateRequest
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
final Task task = r.getTask();
final ActivityStack stack = task.getStack();
beginDeferResume();
try {
r.startFreezingScreenLocked(proc, 0);
......
try {
......
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);
final DisplayContent dc = r.getDisplay().mDisplayContent;
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
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()));
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
......
} catch (RemoteException e) {
r.launchFailed = true;
proc.removeActivity(r);
throw e;
}
} finally {
endDeferResume();
}
return true;
}
该方法执行流程如下:
- 创建 ClientTransaction 实例,设置 mClient 和 mActivityToken,mClient 为当前的 IApplicationThread,mActivityToken 为 IBinder 类型。
- ClientTransaction 实例添加 ClientTransactionItem 类型的接口回调,注意:这里添加的是 LaunchActivityItem 实例,LaunchActivityItem 继承自 ClientTransactionItem 抽象类并实现其中的方法。
- 获取 ClientLifecycleManager 实例,调用其 scheduleTransaction() 方法去调度事务 Transaction 的执行。
6. ClientTransaction 获取、添加事务回调
@UnsupportedAppUsage
private List<ClientTransactionItem> mActivityCallbacks;
private IApplicationThread mClient;
private IBinder mActivityToken;
public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);
if (instance == null) {
instance = new ClientTransaction();
}
instance.mClient = client;
instance.mActivityToken = activityToken;
return instance;
}
public void addCallback(ClientTransactionItem activityCallback) {
if (mActivityCallbacks == null) {
mActivityCallbacks = new ArrayList<>();
}
mActivityCallbacks.add(activityCallback);
}
7. ClientLifecycleManager 调度生命周期有关的事务
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
if (!(client instanceof Binder)) {
transaction.recycle();
}
}
8. ClientTransaction # schedule() 调度事务
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
看一下方法的注释,大概意思是事务初始化之后调度事务,其所有单独部分将按以下顺序发送到客户端:
- 客户端调用 preExecute() 方法,在实际调度事务的回调和生命周期状态请求之前,触发所有需要完成的任务。
- 事务消息已被调度。
- 客户端调用 TransactionExecutor # execute() 方法,执行所有回调和必要的生命周期转换。
通过上面第 5、6 小节的源码解析可以看出,这里的 mClient 是 IApplicationThread 类型的,mClient # scheduleTransaction() 方法这里使用跨进程通信,这时在 system_server 进程中 mClient 作为客户端需要跟服务端进行通信,即 mClient 相当于是服务端的代理。而 ActivityThread 的内部类 ApplicationThread,继承了 IApplicationThread.Stub,即作为服务端接受 system_server 进程中 ATMS 发出的请求并执行。
9. 应用进程 ActivityThread 调度事务
public abstract class ClientTransactionHandler {
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
abstract TransactionExecutor getTransactionExecutor();
abstract void sendMessage(int what, Object obj);
}
public final class ActivityThread extends ClientTransactionHandler {
final H mH = new H();
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
private class ApplicationThread extends IApplicationThread.Stub {
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
}
class H extends Handler {
......
public static final int EXECUTE_TRANSACTION = 159;
public void handleMessage(Message msg) {
......
switch (msg.what) {
......
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
if (isSystem()) {
transaction.recycle();
}
break;
......
}
......
}
}
void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
......
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
......
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
}
执行流程如下:
- ApplicationThread # scheduleTransaction() 方法中又继续调用 ActivityThread # scheduleTransaction() 方法,而 ActivityThread 自身没有这个方法,因此执行父类 ClientTransactionHandler # scheduleTransaction() 方法。
- ClientTransactionHandler # scheduleTransaction() 方法中发送 Handler 消息到 ActivityThread.H 中,H 继承自 Handler,并重写了其 handleMessage() 方法。
- 获取传递过来的 ClientTransaction,并由 TransactionExecutor # execute() 执行该 ClientTransaction。
10. TransactionExecutor 事务执行
public void execute(ClientTransaction transaction) {
final IBinder token = transaction.getActivityToken();
if (token != null) {
final Map<IBinder, ClientTransactionItem> activitiesToBeDestroyed =
mTransactionHandler.getActivitiesToBeDestroyed();
final ClientTransactionItem destroyItem = activitiesToBeDestroyed.get(token);
if (destroyItem != null) {
if (transaction.getLifecycleStateRequest() == destroyItem) {
activitiesToBeDestroyed.remove(token);
}
if (mTransactionHandler.getActivityClient(token) == null) {
Slog.w(TAG, tId(transaction) + "Skip pre-destroyed transaction:\n"
+ transactionToString(transaction, mTransactionHandler));
return;
}
}
}
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
}
@VisibleForTesting
public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
if (callbacks == null || callbacks.isEmpty()) {
return;
}
final IBinder token = transaction.getActivityToken();
ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();
final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState()
: UNDEFINED;
final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);
......
final int postExecutionState = item.getPostExecutionState();
final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
item.getPostExecutionState());
if (closestPreExecutionState != UNDEFINED) {
cycleToPath(r, closestPreExecutionState, transaction);
}
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
if (r == null) {
r = mTransactionHandler.getActivityClient(token);
}
if (postExecutionState != UNDEFINED && r != null) {
final boolean shouldExcludeLastTransition =
i == lastCallbackRequestingState && finalState == postExecutionState;
cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
}
}
}
TransactionExecutor # executeCallbacks() 方法中,执行事务的回调,即第 5 小节中添加到 ClientTransaction 中的 LaunchActivityItem。
11. LaunchActivityItem
public class LaunchActivityItem extends ClientTransactionItem {
@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, mAssistToken, mFixedRotationAdjustments);
client.handleLaunchActivity(r, pendingActions, null );
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
}
ClientTransactionHandler 是一个抽象类,ActivityThread 继承自 ClientTransactionHandler 并实现了其抽象方法,所以这里又回到了 ActivityThread 类,调用其 handleLaunchActivity() 方法来启动 Activity。
12. ActivityThread 启动 Activity
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
......
WindowManagerGlobal.initialize();
GraphicsEnvironment.hintActivityLaunch();
final Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
if (!r.activity.mFinished && pendingActions != null) {
pendingActions.setOldState(r.state);
pendingActions.setRestoreInstanceState(true);
pendingActions.setCallOnPostCreate(true);
}
} else {
try {
ActivityTaskManager.getService()
.finishActivity(r.token, Activity.RESULT_CANCELED, null,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
return a;
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
......
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
......
if (activity != null) {
......
appContext.getResources().addLoaders(
app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
appContext.setOuterContext(activity);
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback,
r.assistToken);
......
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
......
r.activity = activity;
mLastReportedWindowingMode.put(activity.getActivityToken(),
config.windowConfiguration.getWindowingMode());
}
r.setState(ON_CREATE);
synchronized (mResourcesManager) {
mActivities.put(r.token, r);
}
}
......
return activity;
}
performLaunchActivity() 方法执行流程:
- 调用 createBaseContextForActivity() 方法创建 ContextImpl 对象,该方法中调用 ContextImpl # createActivityContext() 方法创建 ContextImpl 对象。
- 调用 Instrumentation # newActivity() 方法加载并新建 Activity,该方法中调用 AppComponentFactory # instantiateActivity() 方法,后通过在 performLaunchActivity() 方法中新建的 ClassLoader 加载新建 Activity 类。
- 通过 LoadApk # makeApplication() 方法创建一个 Application 对象,过程跟加载新建 Activity 类似,用到 ClassLoader。
- 执行 Activity # attach() 方法,ContextImpl 通过该方法来和 Activity 建立关联,除此之外,方法中还完成了 Window 实例的创建并建立自己和 Window 的关联,这样当 Window 接收到外部输入事件后就可以将事件传递给 Activity。
- 执行 Instrumentation # callActivityOnCreate() 方法,该方法中调用 Activity # performCreate() 方法,performCreate() 方法中调用 onCreate() 方法。
13. 小结
总结
|