- 前言
- 一、应用启动进程 Launcher 调用 ATMS 系统进程的过程
- 1. Launcher 桌面的 App 图标入口
- 2. Launcher # startActivitySafely() 方法
- 3. Instrumentation # execStartActivity() 方法
- 二、ATMS 到 Application 的调用过程
- 1. ATMS(ActivityTaskManagerService)
- 2. ActivityStartController
- 3. ActivityStarter
- 4. RootWindowContainer
- 5. ActivityStack
- 6. ActivityStackSupervisor
- 三、AMS 向 Zygote 进程发送启动并孵化应用进程 ActivityThread 的过程
- 1. ActivityTaskManagerService
- 2. ActivityManagerService
- 3. ProcessList
- 4. Process
- 5. ZygoteProcess
- 四、Zygote 进程 fork 并启动应用进程 ActivityThread 的过程
- 1. Zygote 进程启动、解析 Socket 传入的参数
- 2. ZygoteServer 开启 Loop 循环监听 Socket
- 3. ZygoteConnection
- 4. Zygote 创建子进程(native 层创建)
- 5. ZygoteConnection # handleChildProc() 方法
- 6. ZygoteInit # zygoteInit() 方法
- 7. RuntimeInit # applicationInit() 方法
- 8. RuntimeInit # MethodAndArgsCaller
- 五、应用进程启动 ActivityThread
- 总结
前言
面试中经常会被问到,让面试者简述一下 Activity 的启动流程,这个问题是考察面试者对源码的理解程度,要征服面试官获得满意的 offer 还是需要一步步深入去探索一下源码,梳理启动流程并形成自己的总结,而不要死记硬背。
回答这个问题,可以根据 Activity 的启动时机,从两个方面入手:
- 根 Activity 的启动流程: 又叫应用程序启动流程,即点击桌面上某一个应用图标到应用第一个 Activity 展示出来的流程。
- 普通 Activity 的启动流程: 即应用内启动一个 Activity 到展示出来的流程。
由于两种启动流程是有重叠的,根 Activity 的启动流程更复杂,所以下面我们基于 Android R(11.0) 重点分析根 Activity 的启动流程,而普通 Activity 的启动流程在涉及的地方会稍微提一下。
应用的启动流程大致分为下面四个阶段:
一、应用启动进程 Launcher 调用 ATMS 系统进程的过程
二、ATMS 到 Application 的调用过程
三、AMS 向 Zygote 进程发送启动应用进程 ActivityThread 的过程
四、Zygote 进程 fork 并启动应用进程 ActivityThread 的过程
五、应用进程 ActivityThread 启动 Activity 的过程
一、应用启动进程 Launcher 调用 ATMS 系统进程的过程
根 Activity 的启动流程其实就是点击桌面上某一个应用图标到应用第一个 Activity 展示出来的流程,其实 Launcher 桌面实际上就是一个 Activity。当系统开机后,Launcher 也随之被启动,然后将已经安装的应用程序图标显示到桌面上,所以当我们点击一个应用图标其实就是相当于点击 Activity 中的一个 Button,其相应事件就是 Launcher 进程请求 ATMS 来启动该应用程序。
1. Launcher 桌面的 App 图标入口从源码看一下 Launcher 桌面是不是如我们所说的是一个 Activity,源码如下:
public class Launcher extends StatefulActivityimplements LauncherExterns, Callbacks, InvariantDeviceProfile.OnIDPChangeListener, PluginListener , LauncherOverlayCallbacks { @Override @TargetApi(Build.VERSION_CODES.S) protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ...... // 分析1 -- 加载、展示布局文件 inflateRootView(R.layout.launcher); } } public abstract class StatefulActivity > 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,布局文件如下:
这下面就要看看这个 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) {
......
// 这里只分析不使用 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 = 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 设置点击事件 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) {
// 点击 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 );
}
// 调用 Launcher # startActivitySafely() 启动 Activity
launcher.startActivitySafely(v, intent, item);
}
}
回答上面的问题,AllAppsRecyclerView 在 AllAppsContainerView 中设置了 AllAppsGridAdapter,在 AllAppsGridAdapter # onCreateViewHolder() 方法中为子项 itemView 设置点击事件 ItemClickHandler.INSTANCE。
2. Launcher # startActivitySafely() 方法下面回到 Launcher 这个 Activity 中看一下 startActivitySafely() 方法,代码如下:
public class Launcher extends StatefulActivityimplements LauncherExterns, Callbacks, InvariantDeviceProfile.OnIDPChangeListener, PluginListener , 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; // 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。代码如下:
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() 方法。
3. 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);
// 获取 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() 方法。
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
@UnsupportedAppUsage(trackingBug = 129726065)
private static final Singleton IActivityTaskManagerSingleton =
new Singleton() {
@Override
protected IActivityTaskManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
return IActivityTaskManager.Stub.asInterface(b);
}
};
在 Singleton 的 create() 方法中,获取 ActivityTaskManagerService 的引用,这是一个 IBinder 类型的引用,且 ActivityTaskManagerService 作为服务端处于 SystemServer 进程,与当前作为客户端的 Launcher 进程不在同一个进程。 所以这里方法返回的是 IActivityTaskManager.Stub 的代理对象,而 ActivityTaskManagerService 则是对应的实现类,继承了 IActivityTaskManager.Stub 并实现相应的方法,通过代理对象可以跨进程调用服务端 ActivityTaskManagerService 的方法。
二、ATMS 到 Application 的调用过程 1. 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) {
// 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) {
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);
// 检查调用者的进程是否隔离,如果 isIsolated 则抛出 SecurityException 异常
enforceNotIsolatedCaller("startActivityAsUser");
// 检查调用者权限,ATMS 根据传入的 UserId 来确定调用者的权限
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setCallingFeatureId(callingFeatureId)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setUserId(userId)
.execute();
}
// 获取 ActivityStartController
ActivityStartController getActivityStartController() {
return mActivityStartController;
}
2. ActivityStartController
ActivityStarter obtainStarter(Intent intent, String reason) {
return mFactory.obtain().setIntent(intent).setReason(reason);
}
获取 ActivityStarter 对象用来配置并执行启动 Activity。ActivityStarter 是 Android 7.0 中增加的,用来加载启动 Activity 的控制类。
3. ActivityStarterclass 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 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;
}
// 继续调用 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();
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);
// 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(
mTargetStack, mStartActivity, mOptions);
}
}
}
}
在上面的第一步中获取 ActivityStartController,调用其 obtainStarter() 方法,通过内部实现的 DefaultFactory 来获取 ActivityStarter,如果在 mStarterPool 中没有获取到,则新创建一个。
获取到 ActivityStarter 后,通过 Builder 模式设置启动所需的各种参数值,然后执行 ActivityStarter # execute() 方法。
4. RootWindowContainerboolean 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) {
result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
} else if (targetStack == null) {
result |= resumeHomeActivity(null , "no-focusable-task",
display.getDefaultTaskDisplayArea());
}
}
}
return result;
}
5. ActivityStack
@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 );
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 );
// From this point on, if something goes wrong there is no way
// to recover the activity.
try {
next.completeResumeLocked();
} catch (Exception e) {
......
}
} else {
// Whoops, need to restart this activity!
......
mStackSupervisor.startSpecificActivity(next, true, true);
}
return true;
}
ActivityStack 是一个管理类,用来管理系统所有 Activity 的各种状态,其内部维护了 TaskRecord 的列表,因此从 Activity 任务栈这一角度来说,ActivityStack 也可以理解为 Activity 堆栈,它由 ActivityStackSupervisor 来进行管理。
6. ActivityStackSupervisor 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;
// 启动 Activity 的应用程序进程已经创建则继续走 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();
// 不存在则需要创建进程
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);
}
// Post message to start process to avoid possible deadlock of calling into AMS with the
// ATMS lock held.
// 发送 Handler 消息来启动进程,以避免在持有 ATMS 锁的情况下调用 AMS 时可能发生的死锁
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 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 对象,并且只能在同一进程(SystemServer进程)中使用。也就是说 ActivityManagerInternal 实现类 LocalService 是 SystemServer 进程的本地服务 Service,通过本地服务注册到 LocalServices 中,而 AMS 也是运行在 SystemServer 进程,因此可以直接使用 LocalService。
2. ActivityManagerServicepublic 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) {
// If the process is known as top app, set a hint so when the process is
// started, the top priority can be applied immediately to avoid cpu being
// preempted by other processes before attaching the process of top app.
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) {
......
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;
// Start the process. It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
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);
// We can't isolate app data and storage data as parent zygote already did that.
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>
pkgDataInfoMap,
@Nullable Map>
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>
pkgDataInfoMap,
@Nullable Map>
whitelistedDataInfoMap,
boolean bindMountAppsData,
boolean bindMountAppStorageDirs,
@Nullable String[] zygoteArgs) {
// TODO (chriswailes): Is there a better place to check this value?
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>
pkgDataInfoMap,
@Nullable Map>
whitelistedDataInfoMap,
boolean bindMountAppsData,
boolean bindMountAppStorageDirs,
@Nullable String[] extraArgs)
throws ZygoteStartFailedEx {
// 创建字符串列表 argsForZygote,将应用进程的启动参数保持在 argsForZygote 中,包括uid,gid,targetSdkVersion等
ArrayList argsForZygote = new ArrayList<>();
...... // 添加各种参数值
synchronized(mLock) {
// The USAP pool can not be used if the application will not use the systems graphics
// driver. If that driver is requested use the Zygote application start path.
// 调用 zygoteSendArgsAndGetResult(),将传入的应用进程的启动参数 argsForZygote 写入到 ZygoteState 中
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
zygotePolicyFlags, argsForZygote);
}
}
@GuardedBy("mLock")
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
try {
// 与 Zygote 进程建立 Socket 连接
attemptConnectionToPrimaryZygote();
if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}
if (mZygoteSecondarySocketAddress != null) {
// The primary zygote didn't match. Try the secondary.
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 {
......
// 上面 Primary、Secondary 都是调用 ZygoteState.connect() 方法来创建一个包含给定 Zygote socket 地址的 Socket 连接
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;
}
// socket、DataInputStream、BufferedWriter 封装成 ZygoteState 对象供外部调用
return new ZygoteState(zygoteSocketAddress, usapSocketAddress,
zygoteSessionSocket, zygoteInputStream, zygoteOutputWriter,
getAbiList(zygoteOutputWriter, zygoteInputStream));
}
}
// 继续追踪 zygoteSendArgsAndGetResult()
@GuardedBy("mLock")
private Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList args)
throws ZygoteStartFailedEx {
......
if (shouldAttemptUsapLaunch(zygotePolicyFlags, args)) {
try {
return attemptUsapSendArgsAndGetResult(zygoteState, msgStr);
} catch (IOException ex) {
// If there was an IOException using the USAP pool we will log the error and
// attempt to start the process through the Zygote.
Log.e(LOG_TAG, "IO Exception while communicating with USAP pool - "
+ ex.getMessage());
}
}
return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
}
// 用来 fork 出一个新的 Launcher 进程
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();
// Always read the entire result from the input stream to avoid leaving
// bytes in the stream for future process starts to accidentally stumble
// upon.
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 通信时可以用它们进行数据流传输与读取操作。SystemServer 进程通过 BufferedWriter 将参数写给 Zygote 进程的 socket 的 server 端,然后阻塞等待 Zygote 进程的 socket 返回 pid 和 usingWrapper 后封装到 ProcessStartResult。
四、Zygote 进程 fork 并启动应用进程 ActivityThread 的过程 1. Zygote 进程启动、解析 Socket 传入的参数
Android 系统底层是基于 Linux 的,和 Linux 一样,init 进程是 Linux 系统用户进程的第一个进程,它是由 Linux 内核(kenerl)启动的。其它所有的用户进程都是 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);
......
// 调用 runSelectLoop() 开启 Loop 循环来监听 client socket 发来的消息
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
if (zygoteServer != null) {
zygoteServer.closeServerSocket();
}
}
// We're in the child process and have exited the select loop. Proceed to execute the command.
// 子进程的启动
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 socketFDs = new ArrayList<>();
ArrayList peers = new ArrayList<>();
// mZygoteSocket 是服务端的 socket 对象,也就是 Zygote 进程所在 socket 放在 fds[0] 位置
socketFDs.add(mZygoteSocket.getFileDescriptor());
// 刚开始默认 peers[0] = null
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 {
// 处理轮询状态,当 pollFds 有事件到来则往下执行,否则阻塞在这里
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) {
// 采用I/O多路复用机制,当接收到客户端请求到来,则往下执行;否则跳出本次循环。
if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
continue;
}
if (pollIndex == 0) {
// Zygote server socket
// pollIndex==0 上面保存的Zygote socket,表示请求连接
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
socketFDs.add(newPeer.getFileDescriptor());
} else if (pollIndex < usapPoolEventFDIndex) {
// Session socket accepted from the Zygote server socket
// socket 连接成功之后从 Zygote 服务器的 socket 接受到的 Session socket
try {
ZygoteConnection connection = peers.get(pollIndex);
final Runnable command = connection.processOneCommand(this);
// TODO (chriswailes): Is this extra check necessary?
if (mIsForkChild) {
......
return command;
} else {
// 如果不是 fork 子进程则关闭连接,删除当前 fd 消息
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() 方法来接收客户端传输过来的应用进程的启动参数,并执行进程创建工作。
Runnable processOneCommand(ZygoteServer zygoteServer) {
String[] args;
try {
// 读取 client 端 socket write 过来的启动参数
args = Zygote.readArgumentList(mSocketReader);
} catch (IOException ex) {
throw new IllegalStateException("IOException on command socket", ex);
}
......
int pid;
FileDescriptor childPipeFd = null;
FileDescriptor serverPipeFd = null;
// 将数据解析成 ZygoteArguments 格式
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);
}
}
// 将 client 端 fd 和 server 端 fd 存入 fdsToClose 数组中,然后 fd 置位 null
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$();
}
// 调用 forkAndSpecialize() 方法来 fork 子进程
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) {
// in child
// pid = 0 表示创建成功,则进入子进程中
zygoteServer.setForkChild();
// 关闭 socket 连接
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
// 进入子进程执行相关操作
return handleChildProc(parsedArgs, childPipeFd, parsedArgs.mStartChildZygote);
} else {
// In the parent. A pid < 0 indicates a failure and will be handled in handleParentProc.
// pid < 0表示创建失败,则进入父进程返回消息给 client socket 表示启动失败
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
handleParentProc(pid, serverPipeFd);
return null;
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}
该方法主要作用如下:
- 读取 SystemServer 端 socket 写入的数据,并将存入字符串数组的数据封装成 ZygoteArguments 格式。
- 调用 Zygote # forkAndSpecialize() 方法来 fork 子进程,并返回 pid,这里的 pid 并非是进程 id,而是返回结果值,0 表示创建成功,-1 则失败。
- 子进程创建成功后进入子进程执行。
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();
// 通过 JNI 调用 native 层方法
int pid = nativeForkAndSpecialize(
uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
fdsToIgnore, startChildZygote, instructionSet, appDataDir, isTopApp,
pkgDataInfoList, whitelistedDataInfoList, bindMountAppDataDirs,
bindMountAppStorageDirs);
if (pid == 0) {
// Note that this event ends at the end of handleChildProc,
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
// If no GIDs were specified, don't make any permissions changes based on groups.
if (gids != null && gids.length > 0) {
NetworkUtils.setAllowNetworkingForProcess(containsInetGid(gids));
}
}
// Set the Java Language thread priority to the default value for new apps.
Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
ZygoteHooks.postForkCommon();
return pid;
}
方法中调用 native 层的 nativeForkAndSpecialize() 方法创建进程,然后返回进程的 pid(父进程中,返回新建的子进程的 pid,子进程中,则返回 0,出现错误时返回负数),具体 native 层的源码就不跟了,大致看了一下过程:
- 调用 Linux 的 fork() 方法创建进程,设置进程的主线程的 name,如果是 null 或者 SystemServer,则为 SystemServer。
- 调用 CallStaticVoidMethod() 方法返回 Zygote # callPostForkChildHooks() 方法处理 fork 子线程之后的 gc/线程池管理等操作。
private Runnable handleChildProc(ZygoteArguments parsedArgs,
FileDescriptor pipeFd, boolean isZygote) {
// 关闭 socket 连接
closeSocket();
// 设置应用进程的 name
Zygote.setAppProcessName(parsedArgs, TAG);
// End of the postFork event.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
if (parsedArgs.mInvokeWith != null) {
WrapperInit.execApplication(parsedArgs.mInvokeWith,
parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
VMRuntime.getCurrentInstructionSet(),
pipeFd, parsedArgs.mRemainingArgs);
// Should not get here.
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();
// 进程初始化配置,如设置异常捕获 Handler、时区、重置 LogManager 等等
RuntimeInit.commonInit();
// native 层初始化 -- 打开/dev/binder 驱动,映射内核的地址空间,创建 binder 线程用于 IPC 通信
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
classLoader);
}
7. RuntimeInit # applicationInit() 方法
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
// 如果应用程序调用了 System.exit() 方法立即终止进程,可能会导致剩余的运行线程在进程实际退出之前崩溃
nativeSetExitWithoutCleanup(true);
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
VMRuntime.getRuntime().setDisabledCompatChanges(disabledCompatChanges);
final Arguments args = new Arguments(argv);
// The end of of the RuntimeInit event (see #zygoteInit).
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
// Remaining arguments are passed to the start class's static main
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class> cl; // 待加载的 ActivityThread 类
try {
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className, ex);
}
// 获取 main 方法
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);
}
// 判断 main 方法是不是 public 并且 static 类型
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException("Main method is not public and static on " + className);
}
// 返回 Caller,即本小节第一部分的 ZygoteInit.main() 中的 caller
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
总结



