Android系统启动篇
4,《Android SystemServer进程启动流程》
Android系统开发准备篇
3,《Android Framework代码IDE加载和调试》
Android系统开发实践篇
4,《android单独编译framework模块并push》
Android系统开发核心知识储备篇
1,《Android编译系统-envsetup和lunch代码篇》
6,《Android中Activity、View和Window关系详解》
11,《android中AMS进程通知Zygote进程fork新进程的通信方式》
Android核心功能详解篇
2,《Android 手势导航(从下往上滑动进入多任务页面)》
3,《android手势分析(应用界面左往右边滑动退出应用)》
———————————————————————————————————————————
目录
2.1.3 startActivitySafely() 方法
2.2.2 ATMS(ActivityTaskManagerService)
2.3 AMS 向 Zygote 进程发送创建应用进程 ActivityThread 的过程
2.3.2 ActivityTaskManagerService 启动进程
2.3.7 ZygoteProcess 开启 socket 连接
2.4.2 Zygote 进程启动、解析 Socket 传入的参数
2.4.3 ZygoteServer 开启 Loop 循环监听 Socket
2.4.5 Zygote 创建子进程(native 层创建)
2.4.6 ZygoteConnection # handleChildProc() 方法
2.4.7 ZygoteInit # zygoteInit() 方法
2.4.8 RuntimeInit # applicationInit() 方法
2.4.9 RuntimeInit # MethodAndArgsCaller
2.5 应用进程 ActivityThread 启动 Activity 的过程
2.5.3 AMS 绑定 ApplicationThread
2.5.4 ActivityThread 创建并绑定 Application
2.5.5 ProcessRecord 保存 ApplicationThread
2.5.6 ATMS 绑定 WindowProcessController、启动根 Activity
2.5.7 RootWindowContainer 绑定 WindowProcessController
2.5.8 获取 ClientTransaction、添加 Callback、设置 LifecycleStateRequest
2.5.9 ClientTransaction 获取、添加事务回调
2.5.10 ClientLifecycleManager 客户端生命周期事务转换管理器
2.5.11 ClientTransaction # schedule() 调度事务
2.5.13 TransactionExecutor 事务转换执行器
2.5.14 LaunchActivityItem 请求启动 Activity
2.5.15 ActivityThread 执行启动 Activity 事务
2.5.16 ActivityThread 执行生命周期事务
2.5.17 TransactionExecutor 执行中间态生命周期请求事务
2.5.18 TransactionExecutorHelper 获取待执行生命周期的状态序列
2.5.19 TransactionExecutor 执行生命周期事务的最终转换
一,背景介绍
Activity启动流程两种类型:一是在activity中通过startActivity(Intent intent)方法启动一个Activity;二是我们在桌面点击应用图标启动一个App然后显示Activity;第二种方式相较于第一种方式流程更加全面和复杂,所以本文会以第二种流程来分析讲解。
启动流程大致分为下面五个阶段:
1,Launcher进程请求调用ATMS系统进程过程
2,ATMS 向 AMS 发送创建应用进程的过程
3,AMS 向 Zygote 进程发送创建应用进程 ActivityThread 的过程
4,Zygote 进程接收请求 fork 并启动应用进程 ActivityThread 的过程
5,应用进程 ActivityThread 启动 Activity 的过程
二,Activity启动过程
点击 Launcher 中某一个应用图标到应用第一个 Activity 展示出来的流程,当系统开机后,Launcher 会被 AMS 启动,然后将已经安装的应用程序图标显示到桌面上,所以当我们点击一个应用图标其实就是相当于点击 Activity 中的一个 Button,其相应事件就是 Launcher 进程请求 ATMS 来启动该应用程序。
2.1 调用 ATMS 系统进程
2.1.1 时序图
2.1.2 Launcher 桌面的 App 图标入口
Launcher3的manifest.xml定义,路径packages/apps/Launcher3/AndroidManifest.xml
<activity
android:name="com.android.launcher3.Launcher"
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
android:stateNotNeeded="true"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="unspecified"
android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
android:resizeableActivity="true"
android:resumeWhilePausing="true"
android:taskAffinity=""
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY"/>
<category android:name="android.intent.category.LAUNCHER_APP" />
</intent-filter>
<meta-data
android:name="com.android.launcher3.grid.control"
android:value="${packageName}.grid_control" />
</activity>
上面定义可知,com.android.launcher3.Launcher.java文件为桌面首页,源码如下:
public class Launcher extends StatefulActivity<LauncherState> implements LauncherExterns,Callbacks, InvariantDeviceProfile.OnIDPChangeListener, PluginListener<OverlayPlugin>,LauncherOverlayCallbacks {
@Override
@TargetApi(Build.VERSION_CODES.S)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......
// 分析1 -- 加载、展示布局文件
inflateRootView(R.layout.launcher);
}
}
布局文件R.layout.launcher如下,
<!-- R.layout.launcher -->
<?xml version="1.0" encoding="utf-8"?>
<com.android.launcher3.LauncherRootView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:id="@+id/launcher"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<com.android.launcher3.dragndrop.DragLayer
android:id="@+id/drag_layer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:importantForAccessibility="no">
<!-- 这里是展示所有 App 图标的布局,我们只看相关代码 -->
<include
android:id="@+id/apps_view"
layout="@layout/all_apps"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.android.launcher3.dragndrop.DragLayer>
</com.android.launcher3.LauncherRootView>
<!-- R.layout.apps_view -->
<?xml version="1.0" encoding="utf-8"?>
<com.android.launcher3.allapps.LauncherAllAppsContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/apps_view"
android:theme="?attr/allAppsTheme"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="true"
android:clipToPadding="false"
android:focusable="false"
android:saveEnabled="false">
<!-- 展示所有已安装 app 的 AllAppsRecyclerView 继承自 RecyclerView -->
<include
layout="@layout/all_apps_rv_layout"
android:visibility="gone" />
</com.android.launcher3.allapps.LauncherAllAppsContainerView>
<!-- R.layout.all_apps_rv_layout -->
<?xml version="1.0" encoding="utf-8"?>
<com.android.launcher3.allapps.AllAppsRecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/apps_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/search_container_all_apps"
android:clipToPadding="false"
android:descendantFocusability="afterDescendants"
android:focusable="true" />
AllAppsRecyclerView 外层是 LauncherAllAppsContainerView,它是 AllAppsContainerView 的子类。给 AllAppsRecyclerView 设置 Adapter 被封装到了 AllAppsContainerView 里面,看一下代码:
/**
* The all apps view container.
*/
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 是怎么处理点击事件的,代码如下:
/**
* Class for handling clicks on workspace and all-apps items
*/
public class ItemClickHandler {
private static final String TAG = ItemClickHandler.class.getSimpleName();
/**
* Instance used for click handling on items
* 单例方式获取点击事件
*/
public static final OnClickListener INSTANCE = ItemClickHandler::onClick;
private static void onClick(View v) {
if (v.getWindowToken() == null) return;
Launcher launcher = Launcher.getLauncher(v.getContext());
if (!launcher.getWorkspace().isFinishedSwitchingState()) return;
Object tag = v.getTag();
if (tag instanceof WorkspaceItemInfo) {
onClickAppShortcut(v, (WorkspaceItemInfo) tag, launcher);
} else if (tag instanceof FolderInfo) {
if (v instanceof FolderIcon) {
onClickFolderIcon(v);
}
} else if (tag instanceof AppInfo) {
// 点击 App 图标
startAppShortcutOrInfoActivity(v, (AppInfo) tag, launcher
);
} else if (tag instanceof LauncherAppWidgetInfo) {
if (v instanceof PendingAppWidgetHostView) {
onClickPendingWidget((PendingAppWidgetHostView) v, launcher);
}
} else if (tag instanceof SearchActionItemInfo) {
onClickSearchAction(launcher, (SearchActionItemInfo) tag);
}
}
private static void startAppShortcutOrInfoActivity(View v, ItemInfo item, Launcher launcher) {
Intent intent;
if (item instanceof ItemInfoWithIcon
&& (((ItemInfoWithIcon) item).runtimeStatusFlags
& ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE) != 0) {
ItemInfoWithIcon appInfo = (ItemInfoWithIcon) item;
intent = new PackageManagerHelper(launcher)
.getMarketIntent(appInfo.getTargetComponent().getPackageName());
} else {
intent = item.getIntent();
}
if (intent == null) {
throw new IllegalArgumentException("Input must have a valid intent");
}
if (item instanceof WorkspaceItemInfo) {
WorkspaceItemInfo si = (WorkspaceItemInfo) item;
if (si.hasStatusFlag(WorkspaceItemInfo.FLAG_SUPPORTS_WEB_UI)
&& Intent.ACTION_VIEW.equals(intent.getAction())) {
intent = new Intent(intent);
intent.setPackage(null);
}
if ((si.options & WorkspaceItemInfo.FLAG_START_FOR_RESULT) != 0) {
launcher.startActivityForResult(item.getIntent(), 0);
InstanceId instanceId = new InstanceIdSequence().newInstanceId();
launcher.logAppLaunch(launcher.getStatsLogManager(), item, instanceId);
return;
}
}
if (v != null && launcher.supportsAdaptiveIconAnimation(v)) {
// Preload the icon to reduce latency b/w swapping the floating view with the original.
FloatingIconView.fetchIcon(launcher, v, item, true /* isOpening */);
}
// 调用 Launcher # startActivitySafely() 启动 Activity
launcher.startActivitySafely(v, intent, item);
}
}
回答上面的问题,AllAppsRecyclerView 在 AllAppsContainerView 中设置了 AllAppsGridAdapter,在 AllAppsGridAdapter # onCreateViewHolder() 方法中为子项 itemView 设置点击事件 ItemClickHandler.INSTANCE。
2.1.3 startActivitySafely() 方法
/**
* Default launcher application.
*/
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;
}
}
/**
* Extension of BaseActivity allowing support for drag-n-drop
*/
@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() 方法。
2.1.4 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<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 的方法。
2.2 ATMS 向 AMS 发送创建应用进程的过程
system_server 进程中 startBootstrapServices() 方法启动系统引导服务,引导服务中启动了 ATMS(ActivityTaskManagerServici)、AMS 等服务,其中 ATMS 是 Android 10 中新增的,本来都是 AMS 来管理,Google 考虑到 AMS 职责太多、代码太庞大,所以单独拆出来 ATMS 用于管理 Activity及其容器类,如 Task、Stack、Display 等,分担 AMS 部分职责。
2.2.1 时序图
2.2.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) {
// 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 /*validateIncomingUser*/);
}
private int startActivityAsUser(IApplicationThread caller, String callingPackage,
@Nullable String callingFeatureId, Intent intent, String resolvedType,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
assertPackageMatchesCallingUid(callingPackage);
// 检查调用者的进程是否隔离,如果 isIsolated 则抛出 SecurityException 异常
enforceNotIsolatedCaller("startActivityAsUser");
// 检查调用者权限,ATMS 根据传入的 UserId 来确定调用者的权限
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
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.2.3 ActivityStartController
/**
* @return A starter to configure and execute starting an activity. It is valid until after
* {@link ActivityStarter#execute} is invoked. At that point, the starter should be
* considered invalid and no longer modified or used.
*/
ActivityStarter obtainStarter(Intent intent, String reason) {
return mFactory.obtain().setIntent(intent).setReason(reason);
}
获取 ActivityStarter 对象后通过 Builder 模式设置启动所需的各种参数值,然后执行启动 Activity。ActivityStarter 是 Android 7.0 中增加的,用来加载启动 Activity 的控制类。
2.2.4 ActivityStarter
class ActivityStarter {
@VisibleForTesting
interface Factory {
// Sets the {@link ActivityStartController} to be passed to {@link ActivityStarter}.
void setController(ActivityStartController controller);
// 生成一个准备处理新启动请求的 ActivityStarter,ActivityStartController 持有这个实例对象
ActivityStarter obtain();
// Recycles a starter for reuse.
void recycle(ActivityStarter starter);
}
// Default implementation of {@link StarterFactory}.
static class DefaultFactory implements Factory {
// 被激活的启动器的最大数
private final int MAX_STARTER_COUNT = 3;
private ActivityStartController mController;
private ActivityTaskManagerService mService;
private ActivityStackSupervisor mSupervisor;
private ActivityStartInterceptor mInterceptor;
private SynchronizedPool<ActivityStarter> mStarterPool =
new SynchronizedPool<>(MAX_STARTER_COUNT);
DefaultFactory(ActivityTaskManagerService service,
ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
mService = service;
mSupervisor = supervisor;
mInterceptor = interceptor;
}
@Override
public void setController(ActivityStartController controller) {
mController = controller;
}
@Override
public ActivityStarter obtain() {
ActivityStarter starter = mStarterPool.acquire();
if (starter == null) {
starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
}
return starter;
}
@Override
public void recycle(ActivityStarter starter) {
starter.reset(true /* clearRequest*/);
mStarterPool.release(starter);
}
}
/**
* Resolve necessary information according the request parameters provided earlier, and execute
* the request which begin the journey of starting an activity.
* @return The starter result.
*/
int execute() {
try {
int res;
synchronized (mService.mGlobalLock) {
final boolean globalConfigWillChange = mRequest.globalConfig != null
&& mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0;
final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack();
if (stack != null) {
stack.mConfigWillChange = globalConfigWillChange;
}
final long origId = Binder.clearCallingIdentity();
res = resolveToHeavyWeightSwitcherIfNeeded();
if (res != START_SUCCESS) {
return res;
}
// 继续调用 executeRequest() 方法
res = executeRequest(mRequest);
Binder.restoreCallingIdentity(origId);
if (globalConfigWillChange) {
......
mService.updateConfigurationLocked(mRequest.globalConfig, null, false);
}
// Notify ActivityMetricsLogger that the activity has launched.
// ActivityMetricsLogger will then wait for the windows to be drawn and populate
// WaitResult.
mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,
mLastStartActivityRecord);
return getExternalResult(mRequest.waitResult == null ? res
: waitForResult(res, mLastStartActivityRecord));
}
} finally {
onExecutionComplete();
}
}
private int executeRequest(Request request) {
......
// 创建 ActivityRecord,保存 Activity 的所有信息
final ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
callingPackage, callingFeatureId, intent, resolvedType, aInfo,
mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode,
request.componentSpecified, voiceSession != null, mSupervisor, checkedOptions,
sourceRecord);
mLastStartActivityRecord = r;
......
final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack();
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
restrictedBgActivity, intentGrants);
......
return mLastStartActivityResult;
}
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
boolean restrictedBgActivity, NeededUriGrants intentGrants) {
int result = START_CANCELED;
try {
mService.deferWindowLayout();
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
}
......
return result;
}
@VisibleForTesting
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
boolean restrictedBgActivity, NeededUriGrants intentGrants) {
......
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTask().topRunningActivityLocked();
if (!mTargetStack.isTopActivityFocusable()
|| (topTaskActivity != null && topTaskActivity.isTaskOverlay()
&& mStartActivity != topTaskActivity)) {
......
mTargetStack.ensureActivitiesVisible(null /* starting */,
0 /* configChanges */, !PRESERVE_WINDOWS);
// Go ahead and tell window manager to execute app transition for this activity
// since the app transition will not be triggered through the resume channel.
mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
} else {
......
mRootWindowContainer.resumeFocusedStacksTopActivities(
mTargetStack, mStartActivity, mOptions);
}
}
}
}
在上面的第一步中获取 ActivityStartController,调用其 obtainStarter() 方法,通过内部实现的 DefaultFactory 来获取 ActivityStarter,如果在 mStarterPool 中没有获取到,则新创建一个。
上面介绍了 ActivityStarter 类是用来加载启动 Activity 的控制类,在ActivityStarter # execute() 方法中,会继续调用 ActivityStarter # executeRequest() 方法,这里会处理启动 Activity 的请求,并开始一个 Activity 启动的流程。
ActivityStarter # executeRequest() 方法会进行初步的检查并且确认权限,并且在这里组装对应 Activity 的 ActivityRecord,其包含了对应 Activity 的所有信息,并储存在任务栈 TaskRecord 中。在 Activity 的启动过程中,Activity 都是通过 ActivityRecord 来表示的。然后继续调用 ActivityStarter # startActivityUnchecked() 方法,接着 ActivityStarter # startActivityUnchecked() 方法会调用 ActivityStarter # startActivityInner() 方法。
在 ActivityStarter # startActivityInner() 方法中,主要就是处理 Activity 的启动模式有关的逻辑,并且在 ActivityStack 中处理对应 Activity 在任务栈中的相关事宜,包括但不限于将对应的 ActivityRecord 添加到 TaskRecord 栈中、将对应的 ActivityRecord 提到 TaskRecord 栈中最顶部。
最后调用 RootWindowContainer # resumeFocusedStacksTopActivities() 方法,将启动流程交给 RootWindowContainer 处理。
2.2.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) {
// 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 /* prev */, "no-focusable-task",
display.getDefaultTaskDisplayArea());
}
}
}
return result;
}
RootWindowContainer 是窗口容器(WindowContainer)的根容器,管理所有的窗口容器,设备上所有的窗口(Window)、显示(Display)都是由它来管理的。
RootWindowContainer # resumeFocusedStacksTopActivities() 方法会恢复对应任务栈顶部的 Activity,方法中会检查一些可见性相关的属性,后转交给 ActivityStack # resumeTopActivityUncheckedLocked() 方法来继续启动流程。
2.2.6 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 /* focusableOnly */);
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 /* updateServiceConnectionActivities */,
true /* activityChange */, true /* updateOomAdj */,
true /* addPendingTopUid */);
// From this point on, if something goes wrong there is no way
// to recover the activity.
try {
next.completeResumeLocked();
} catch (Exception e) {
......
mStackSupervisor.startSpecificActivity(next, true, false);
return true;
}
} else {
// Whoops, need to restart this activity!
......
}
return true;
}
ActivityStack 是一个管理类,用来管理系统所有 Activity 的各种状态,其内部维护了 TaskRecord 的列表,每个 TaskRecord 又包含了若干个 ActivityRecord,每个 ActivityRecord 对应了一个 Activity。这里 TaskRecord 相当于在启动模式中的“任务栈”,根据启动模式的不同,在启动 Activity 的时候,会对 TaskRecord 进行不同的操作。
由于前一步已经将对应 Activity 的 ActivityRecord 添加到了栈顶,所以 ActivityStack # resumeTopActivityUncheckedLocked() 方法恢复的就是将启动的栈顶 Activity,然后继续调用 ActivityStack # resumeTopActivityInnerLocked() 方法来继续启动流程,该方法中做了一系列判断,确保待启动 Activity 可见性、预定 Activity 的切换动画等。后转交给 ActivityStackSupervisor # startSpecificActivity() 方法来启动栈顶特定的 Activity。
2.2.7 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;
// wpc.hasThread() 内部通过判断 IApplicationThread 是否被赋值,如果已赋值,即应用进程已运行
// 启动 Activity 的应用程序进程已经创建运行则走 Activity 的生命周期
// 即普通 Activity 的启动走 realStartActivityLocked() 方法继续 Activity 的创建
if (wpc != null && wpc.hasThread()) {
try {
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
......
}
// If a dead object exception was thrown -- fall through to
// restart the application.
knownToBeDead = true;
}
r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
final boolean isTop = andResume && r.isTopRunningActivity();
// 如果未赋值,即应用进程还不存在,则需要创建应用进程,由于是根 Activity 的启动所以应用进程还未被创建并启动
mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
}
ActivityStackSupervisor 是用来辅助 ATMS 对 Activity 和 Task 进行管理的,其中 ActivityStackSupervisor 是对 ActivityStack 进行管理的,用 ActivityStack 对 Acitivity 进行状态管理。
ActivityStackSupervisor 内部管理了 mHomeStack、mFocusedStack 和 mLastFocusedStack 三个 ActivityStack:
1,mHomeStack 管理的是 Launcher 相关的 Activity 栈,stackId为0。
2,mFocusedStack 管理的是当前显示在前台 Activity 的 Activity 栈。
3,mLastFocusedStack 管理的是上一次显示在前台 Activity 的 Activity 栈。
ActivityStackSupervisor # startSpecificActivity() 方法中获取 WindowProcessController ,通过 wpc # hasThread() 方法判断应用进程是否已创建并运行中,其内部是通过 IApplicationThread 是否已经被赋值来判断的,如果已被赋值则表示应用进程已创建且运行中,此时进入判断体内部,走 ActivityStackSupervisor # realStartActivityLocked() 方法继续 Activity 的启动流程,即普通 Activity 的启动流程。如果未被赋值,则需要创建应用进程,这里由于是根 Activity 的启动所以应用进程还未被创建并启动。
2.3 AMS 向 Zygote 进程发送创建应用进程 ActivityThread 的过程
2.3.1 时序图
![](https://i-blog.csdnimg.cn/blog_migrate/9399f5ebac1e77a85216a8c854e38822.png)
2.3.2 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 <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.3.3 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) {
// 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 /* intentFlags */,
new HostingRecord(hostingType, hostingName, isTop),
ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
false /* isolated */, true /* keepIfLarge */);
}
} 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 /* isolatedUid */,
keepIfLarge, null /* ABI override */, null /* entryPoint */,
null /* entryPointArgs */, null /* crashHandler */);
}
}
startProcess() 方法调用 AMS # startProcessLocked() 方法,并返回 ProcessRecord 实例记录管理启动进程的信息。
2.3.4 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 记录每个进程的信息,进程名、uid 等
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 /* disableHiddenApiChecks */, false /* disableTestApiChecks */,
false /* mountExtStorageFull */, abiOverride);
}
/**
* @return {@code true} if process start is successful, false otherwise.
*/
@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.
// 配置新创建进程的启动文件:ActivityThread,经过层层封装后经 Socket 传输到 Zygote 进程
// Zygote 进程 fork 出新进程后要加载启动的类文件名
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,
/*zygotePolicyFlags=*/ 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() 继续追踪源码。
2.3.5 Process
/**
* State associated with the zygote process.
* @hide
*/
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);
}
ZYGOTE_PROCESS 是 ZygoteProcess 在 Process 类中的静态实例,所以流程调用走到 Process # start() 方法继续进程的启动流程。
2.3.6 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) {
// TODO (chriswailes): Is there a better place to check this value?
if (fetchUsapPoolEnabledPropWithMinInterval()) {
informZygotesOfUsapPoolStatus();
}
try {
// 继续调用 startViaZygote,即通过 Zygote 来启动进程
return startViaZygote(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ 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 {
// 创建字符串列表 argsForZygote,将应用进程的启动参数保存在 argsForZygote 中
// 包括 uid、gid、targetSdkVersion、应用程序进程启动文件:android.app.ActivityThread 等参数
ArrayList<String> argsForZygote = new ArrayList<>();
...... // 添加各种参数值
argsForZygote.add(processClass);
......
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);
}
}
ZygoteProcess # start() 方法中,继续调用 ZygoteProcess # startViaZygote() 方法,即通过 Zygote 来启动进程,方法流程如下:
建字符串列表 argsForZygote,将应用进程的启动参数保存在 argsForZygote 列表中,包括 uid、gid、targetSdkVersion、应用进程的启动文件:android.app.ActivityThread 等参数。
调用 ZygoteProcess # openZygoteSocketIfNeeded() 方法,如果与 Zygote 进程的 socket 连接未开启,则尝试开启,可能会产生阻塞和重试。连接调用的是 ZygoteState # connect() 方法,ZygoteState 是 ZygoteProcess 的内部类。
调用 ZygoteProcess # zygoteSendArgsAndGetResult() 方法,向 Zygote 进程发送参数列表,启动一个新的子进程并返回子进程的 pid。注意:当前实现将参数列表中的换行符替换为空格。
2.3.7 ZygoteProcess 开启 socket 连接
@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));
}
}
ZygoteProcess # openZygoteSocketIfNeeded() 方法,打开与 Zygote 进程的 socket 连接,如果连接未建立,则尝试调用 ZygoteState # connect() 方法创建一个使用给定 Zygote socket 地址的 Socket 连接,然后连接到 Zygote 的远程服务端,同时创建 BufferedWriter 和 DataInputStream 进行参数数据的传输与读取,最后将 socket、DataInputStream、BufferedWriter 等封装成 ZygoteState 对象供外部调用。
2.3.8 ZygoteProcess 发送请求参数
@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) {
// 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() 方法中使用创建的 ZygoteState 中保存的 BufferedWriter 和 DataInputStream 来进行 Socket 通信,通过它们进行数据流的传输与读取操作。system_server 进程通过 BufferedWriter 将参数写给 Zygote 进程的 socket 的 server 端,然后阻塞等待 Zygote 进程的 socket 返回 pid 和 usingWrapper 后封装到 ProcessStartResult。
2.4 Zygote 进程fork并启动应用进程
2.4.1 时序图
2.4.2 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);
......
// 调用 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 实例对象,调用 ZygoteServer # runSelectLoop() 方法开启 loop 无限循环来监听 client socket 发来的消息,当接收到创建新进程的请求时,立即唤醒并执行相应工作。如果 fork 出系统进程,则加入到列表,然后继续阻塞等待;如果 fork 出子进程,则退出 loop 循环,返回创建的应用子进程,并执行子进程的启动。
2.4.3 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();
}
/**
* Runs the zygote process's select loop. Accepts new connections as
* they happen, and reads commands from connections one spawn-request's
* worth at a time.
*/
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> socketFDs = new ArrayList<>();
ArrayList<ZygoteConnection> 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多路复用 epoll 机制,当接收到客户端请求到来,则往下执行;否则跳出本次循环
if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
continue;
}
if (pollIndex == 0) {
// Zygote server socket
// pollIndex==0 表示有新的客户端请求连接到来,调用server socket端的 accpet 函数建立通信连接
// zygote 进程与 system server 进程建立了连接
ZygoteConnection newPeer = acceptCommandPeer(abiList);
// 加入到 peers 和 fds, 即开始下一次监听
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 进程建立起连接,其方法流程如下:
开启 Loop 死循环监听 socket 事件,没有连接时就阻塞在那里,当有连接到来时唤醒继续往下执行。
pollIndex==0 时,说明收到请求连接的事件,请求和 Zygote 建立 socket 连接,调用 acceptCommandPeer() 方法创建 ZygoteConnection 对象,并调用 mZygoteSocket # accept() 方法建立 socket 连接,然后添加到监听列表 peers 中,等待与该 socket 有关的命令的到来。
pollIndex < usapPoolEventFDIndex 时,表示是已经连接的 socket 上的命令到来,此时调用 ZygoteConnection # processOneCommand() 方法来接收客户端传输过来的应用进程的启动参数,并执行进程创建工作,处理完后,就会断开与客户端的连接,并把用于连接的 socket 从监听列表 peers 中移除。
2.4.4 ZygoteConnection
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);
}
}
该方法主要作用如下:
读取 system_server 端 socket 写入的数据,并将存入字符串数组的数据封装成 ZygoteArguments 格式。
调用 Zygote # forkAndSpecialize() 方法来 fork 子进程,并返回 pid,这里的 pid 并非是进程 id,而是返回结果值,0 表示创建成功,-1 则失败。
子进程创建成功后进入子进程执行。
2.4.5 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();
// 通过 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 或者 system_server,则为 system_server。
调用 CallStaticVoidMethod() 方法返回 Zygote # callPostForkChildHooks() 方法处理 fork 子线程之后的 gc/线程池管理等操作。
2.4.6 ZygoteConnection # handleChildProc() 方法
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 /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
}
}
}
该方法就是进入子进程执行不同的初始化操作,因为已经 fork() 成功,关闭 socket 连接等释放资源,设置应用进程的 name,最后调用 ZygoteInit # zygoteInit() 方法初始化 Zygote。
2.4.7 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);
}
方法流程如下:
日志流重定向,将系统输出和系统错误重定向到 Android 日志。
进程初始化配置,如设置异常捕获 Handler、时区、重置 LogManager 等等。
native 层初始化,打开 /dev/binder 驱动,映射内核的地址空间,创建 binder 线程用于 IPC 通信。
调用 RuntimeInit # applicationInit() 方法,返回创建的 Runnable 对象。
2.4.8 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) {
// 待加载的类、这里是指 ActivityThread,也就是我们第三节中在 ProcessList 中指明的 entryPoint
Class<?> cl;
try {
// 加载 android.app.ActivityThread 类
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className, ex);
}
// 获取 main 方法
Method m;
try {
// 获取 ActivityThread # main() 函数
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 接口。即返回到 2. Zygote 进程启动、解析 Socket 传入的参数 这节中 ZygoteInit # main() 方法的 caller,如果 caller!=null 会调用这个 Runnable 的 run() 方法。
2.4.9 RuntimeInit # MethodAndArgsCaller
static class MethodAndArgsCaller implements Runnable {
/** method to call */
private final Method mMethod;
/** argument array */
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。
2.4.10. 小结
Zygote 进程启动流程:
init 进程为用户空间(相对于内核空间)的第一个进程,根据 init.rc 启动 Zygote 进程。
Zygote 进程启动步骤:创建虚拟机、注册JNI、执行 ZygoteInit # main() 方法。
Zygote 进程启动 system_server 进程(Zygote 启动的第一个进程),这个本小节没有具体分析。
Zygote 创建 socket 连接通道,阻塞并等待新建进程的指令到来,通过 fork 新建用户进程。
Zygote 新加了一个优化进程创建的机制,UsapPool - 池化机制,我跟了一下源码,是预先缓存了几个进程。
2.5 应用进程 ActivityThread 启动 Activity 的过程
ActivityThread 类是应用初始化类,它的 main() 方法是应用的入口方法,它也是我们说的“主线程”,但是 ActivityThread 本身不是一个线程,之所以称它为“主线程”,是因为它运行在主线程中。所以说 ActivityThread 是主线程的一部分,但不并能代表主线程。
1,ActivityThread 负责创建 Application 对象以及管理其生命周期方法调用。
2,ActivityThread 管理着四大组件的生命周期方法调用。
2.5.1 时序图
2.5.2 ActivityThread 入口方法
public final class ActivityThread extends ClientTransactionHandler {
// 初始化 ApplicationThread
final ApplicationThread mAppThread = new ApplicationThread();
// 初始化 Handler,ApplicationThread 和 ActivityThread 通信使用
final H mH = new H();
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
......
// Call per-process mainline module initialization.
initializeMainlineModules();
Process.setArgV0("<pre-initialized>");
// 初始化主线程的 Looper
Looper.prepareMainLooper();
...... // 获取 startSeq
// 实例化 ActivityThread
ActivityThread thread = new ActivityThread();
//
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
// sMainThreadHandler = mH
sMainThreadHandler = thread.getHandler();
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
// 开启 Looper 循环,等待接收消息
Looper.loop();
// 正常不会走到这里,除非是非正常退出了 looper 循环
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);
}
......
} 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();
}
......
}
......
}
}
ActivityThread # attach() 方法中,使用 Binder 通信跨进程调用到 system_server 进程中 AMS 的 attachApplication() 方法,并将 ApplicationThread 作为参数传递过去。
2.5.3 AMS 绑定 ApplicationThread
// ActivityTaskManagerInternal 是一个抽象类,实现类是 ATMS 的内部类 LocalService
// ATMS 启动的时候,通过 LocalServices # addService() 注册到 LocalServices
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;
......
try {
......
// 跨进程调用应用进程 ApplicationThread # bindApplication()创建绑定 Application
thread.bindApplication(processName, appInfo, providerList, null, profilerInfo,
null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.compat, getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions,
app.mDisabledCompatChanges);
// Make app active after binding application or client may be running requests (e.g
// starting activities) before it is ready.
// 保存 应用进程 IApplicationThread
app.makeActive(thread, mProcessStats);
......
}
......
boolean didSomething = false;
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
try {
// 通过 ATMS 启动根 Activity
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
}
......
}
return true;
}
AMS # attachApplication() 方法,在获取到 pid、uid 后继续调用 AMS # attachApplicationLocked() 方法。
AMS # attachApplicationLocked() 方法中关注以下流程:
通过跨进程通信调用应用进程中 ApplicationThread # bindApplication() 创建并绑定 Application。
ProcessRecord 调用 makeActive() 方法保存应用进程 IApplicationThread。通过 ActivityTaskManagerInternal 本地服务过渡到 ATMS 启动根 Activity。
2.5.4 ActivityThread 创建并绑定 Application
IApplicationThread # bindApplication() 方法调用的是应用进程中的实现类 ApplicationThread # bindApplication() 方法,方法中通过内部类 H 发送 Handler 消息,进而调用到 ActivityThread # handleBindApplication() 方法,代码如下:
@UnsupportedAppUsage
private void handleBindApplication(AppBindData data) {
......
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
updateLocaleListFromAppContext(appContext,
mResourcesManager.getConfiguration().getLocales());
......
if (ii != null) {
......
final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
appContext.getClassLoader(), false, true, false);
final ContextImpl instrContext = ContextImpl.createAppContext(this, pi,
appContext.getOpPackageName());
try {
// 获取 ClassLoader 加载类文件
final ClassLoader cl = instrContext.getClassLoader();
// 获取 Instrumentation 类并构建实例对象
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
}
......
final ComponentName component = new ComponentName(ii.packageName, ii.name);
mInstrumentation.init(this, instrContext, appContext, component,
data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
......
}
......
Application app;
......
try {
// 创建 Application
app = data.info.makeApplication(data.restrictedBackupMode, null);
......
mInitialApplication = app;
......
try {
mInstrumentation.onCreate(data.instrumentationArgs);
}
......
try {
// 内部调用 Application # onCreate() 的方法
// 故 Application # onCreate() 比 ActivityThread 的 main() 方法慢执行
// 但是会比所有该应用 Activity 的生命周期先调用,因为此时的 Activity 还没启动
mInstrumentation.callApplicationOnCreate(app);
}
......
}
......
}
2.5.5 ProcessRecord 保存 ApplicationThread
public void makeActive(IApplicationThread _thread, ProcessStatsService tracker) {
......
thread = _thread;
mWindowProcessController.setThread(thread);
}
方法内将流程交给 WindowProcessController 并调用其 setThread() 方法存储 IApplicationThread,代码如下:
public class WindowProcessController extends ConfigurationContainer<ConfigurationContainer>
implements ConfigurationContainerListener {
private IApplicationThread mThread;
@HotPath(caller = HotPath.PROCESS_CHANGE)
public void setThread(IApplicationThread thread) {
synchronized (mAtm.mGlobalLockWithoutBoost) {
mThread = thread;
if (thread != null) {
setLastReportedConfiguration(getConfiguration());
}
}
}
IApplicationThread getThread() {
return mThread;
}
boolean hasThread() {
return mThread != null;
}
}
WindowProcessController # setThread() 方法中将传入的 IApplicationThread 赋值给 mThread 中保存,此时 WindowProcessController 中的 IApplicationThread 才有值,同时也解释了第二部分最后提出的问题。而我们在启动根 Activity 的时候,在第二部分的 7. ActivityStackSupervisor 的 startSpecificActivity() 方法中通过 wpc.hasThread() 是获取不到 IApplicationThread,是因为那时应用进程还没创建好,也就没有给 WindowProcessController 中的 IApplicationThread 赋值。
2.5.6 ATMS 绑定 WindowProcessController、启动根 Activity
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
// 启动的时候注册到 LocalServices 中
private void start() {
LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
}
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 {
// 调用 RootWindowContainer # attachApplication()
return mRootWindowContainer.attachApplication(wpc);
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
}
......
}
}
ActivityTaskManagerInternal 是一个抽象类,实现类是 ATMS 的内部类 LocalService,这是一个本地服务,在 ATMS 启动的时候,通过 LocalServices # addService() 注册到 LocalServices 中。在 AMS 的构造方法中通过 LocalServices # getService() 方法获取到注册的本地服务。所以 AMS 中调用 ActivityTaskManagerInternal 的方法,实际上调用的是 ATMS 中的 实现类 LocalService 的方法。该方法继续调用 RootWindowContainer # attachApplication() 方法,启动流程交给 RootWindowContainer 处理。
2.5.7 RootWindowContainer 绑定 WindowProcessController
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; // Set to true if an activity was started.
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 /* preserve_windows */);
}
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 /*andResume*/,
true /*checkConfig*/)) {
mTmpBoolean = true;
}
} catch (RemoteException e) {
.....
return true;
}
return false;
}
RootWindowContainer # attachApplication() 方法中,调用到 RootWindowContainer # startActivityForAttachedApplicationIfNeeded() 方法,如何调用到的该方法可以参考第三部分 2. ActivityTaskManagerService 启动进程。RootWindowContainer # startActivityForAttachedApplicationIfNeeded() 方法中继续调用 ActivityStackSupervisor # realStartActivityLocked() 方法来真正的启动 Activity。
2.5.8 获取 ClientTransaction、添加 Callback、设置 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 {
......
// Create activity launch transaction.
// 获取 ClientTransaction 实例
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);
final DisplayContent dc = r.getDisplay().mDisplayContent;
// ClientTransaction 实例添加 ClientTransactionItem 类型的回调消息
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
r.assistToken, r.createFixedRotationAdjustmentsIfNeeded()));
// 所需的最终生命周期状态请求
final ActivityLifecycleItem lifecycleItem;
// 判断此时的生命周期状态是走 onResume 还是 onPause
if (andResume) {
// 由于此时 ActivityStack 栈中只有一个 Activity,所以 top == r 为 true,因此应赋值为 ResumeActivityItem
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
// 设置执行 transaction 后的最终的生命周期状态请求
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// ClientLifecycleManager 调度 ClientTransaction
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
......
} catch (RemoteException e) {
// 启动失败,移除 ActivityRecord
r.launchFailed = true;
proc.removeActivity(r);
throw e;
}
} finally {
endDeferResume();
}
return true;
}
该方法执行流程如下:
创建 ClientTransaction 实例,其中参数 proc.getThread() 是 IApplicationThread 类型,mActivityToken 为 IBinder 类型。
ClientTransaction 实例添加 ClientTransactionItem 类型的回调消息,注意:这里添加的是 LaunchActivityItem 实例,LaunchActivityItem 继承自 ClientTransactionItem 抽象类并实现其中的方法。
获取 ClientLifecycleManager 实例,调用其 scheduleTransaction() 方法去调度转换事务 Transaction 的执行。
2.5.9 ClientTransaction 获取、添加事务回调
// 客户端的单个回调列表
@UnsupportedAppUsage
private List<ClientTransactionItem> mActivityCallbacks;
// 执行事务后客户端活动应处于的最终生命周期状态
private ActivityLifecycleItem mLifecycleStateRequest;
/** Target client. */
private IApplicationThread mClient;
/** Target client activity. Might be null if the entire transaction is targeting an app. */
private IBinder mActivityToken;
/** Obtain an instance initialized with provided params. */
// 获取 ClientTransaction 实例
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;
}
/**
* 在 ClientTransaction 的 callbacks 列表尾部添加 ClientTransactionItem 类型的消息
* 参数:包含生命周期请求或回调的单个消息
* @param activityCallback A single message that can contain a lifecycle request/callback.
*/
public void addCallback(ClientTransactionItem activityCallback) {
if (mActivityCallbacks == null) {
mActivityCallbacks = new ArrayList<>();
}
mActivityCallbacks.add(activityCallback);
}
/**
* Set the lifecycle state in which the client should be after executing the transaction.
* 设置客户端在执行事务后应处于的生命周期状态
* @param stateRequest A lifecycle request initialized with right parameters.
*/
public void setLifecycleStateRequest(ActivityLifecycleItem stateRequest) {
mLifecycleStateRequest = stateRequest;
}
ClientTransaction 是保存一系列待发送给客户端处理的事务消息的容器,包括一个 Callback 列表和一个最终生命周期状态。
2.5.10 ClientLifecycleManager 客户端生命周期事务转换管理器
/**
* Schedule a transaction, which may consist of multiple callbacks and a lifecycle request.
* 安排调度一个事务(启动、暂停等 Activity 事务),可能包含多个回调和一个生命周期请求
* @param transaction A sequence of client transaction items.
* @throws RemoteException
*
* @see ClientTransaction
*/
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
if (!(client instanceof Binder)) {
// If client is not an instance of Binder - it's a remote call and at this point it is
// safe to recycle the object. All objects used for local calls will be recycled after
// the transaction is executed on client in ActivityThread.
transaction.recycle();
}
}
ClientLifecycleManager 能够组合多个客户端生命周期转换请求与回调,并将其作为单个事务调度执行。
2.5.11 ClientTransaction # schedule() 调度事务
/**
* Schedule the transaction after it was initialized. It will be send to client and all its
* individual parts will be applied in the following sequence:
* 1. The client calls {@link #preExecute(ClientTransactionHandler)}, which triggers all work
* that needs to be done before actually scheduling the transaction for callbacks and
* lifecycle state request.
* 2. The transaction message is scheduled.
* 3. The client calls {@link TransactionExecutor#execute(ClientTransaction)}, which executes
* all callbacks and necessary lifecycle transitions.
*/
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
看一下方法的注释,大概意思是事务初始化之后调度事务,其所有单独部分将按以下顺序发送到客户端:
客户端调用 preExecute() 方法,在实际调度事务的回调和生命周期状态请求之前,触发所有需要完成的任务。
事务消息已被调度。
客户端调用 TransactionExecutor # execute() 方法,执行所有回调和必要的生命周期转换。
通过上面第 8、9 小节的源码解析可以看出,这里 mClient 是 IApplicationThread 类型,它是极其重要的一个 Binder 接口,维护了应用进程和 system_server 进程中 AMS 之间的 IPC 通讯,mClient 就是应用进程在系统进程中的代理对象,AMS 通过 mClient 与此时作为服务端的应用进程进行通信。而应用进程中的实现类 ApplicationThread 是 ActivityThread 的内部类,继承自 IApplicationThread.Stub,实现了 Binder 接口,此时作为服务端接受 system_server 进程中 AMS 发出的请求并执行,也就是流程切到应用进程继续执行。
2.5.12 ActivityThread 调度事务
public abstract class ClientTransactionHandler {
/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
// 发送 Handler 消息到 ActivityThread.H 中
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
/**
* Get the {@link TransactionExecutor} that will be performing lifecycle transitions and
* callbacks for activities.
*/
abstract TransactionExecutor getTransactionExecutor();
// ActivityThread 实现该抽象方法,然后调用其内部的 mH 发送消息并处理
abstract void sendMessage(int what, Object obj);
}
public final class ActivityThread extends ClientTransactionHandler {
final H mH = new H();
// An executor that performs multi-step transactions.
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
// 应用进程中 IApplicationThread 的实现类,继续调用 ActivityThread 的方法
private class ApplicationThread extends IApplicationThread.Stub {
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
// 执行父类 ClientTransactionHandler # scheduleTransaction()
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:
// 获取传递过来的 ClientTransaction
final ClientTransaction transaction = (ClientTransaction) msg.obj;
// TransactionExecutor
mTransactionExecutor.execute(transaction);
if (isSystem()) {
// Client transactions inside system process are recycled on the client side
// instead of ClientLifecycleManager to avoid being cleared before this
// message is handled.
transaction.recycle();
}
// TODO(lifecycler): Recycle locally scheduled transactions.
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 的实现类 H 发送消息到 ActivityThread 中,并重写了其 handleMessage() 方法。
H # handleMessage() 方法中获取传递过来的 ClientTransaction,并由 TransactionExecutor # execute() 执行该 ClientTransaction 的转换。
2.5.13 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) {
// 执行销毁与该 token 有关的 Activity 的事务,然后与此有关的记录将被移除
activitiesToBeDestroyed.remove(token);
}
if (mTransactionHandler.getActivityClient(token) == null) {
// Activity 还未完成创建就请求销毁,所以与这个 token 有关的事务都要取消
Slog.w(TAG, tId(transaction) + "Skip pre-destroyed transaction:\n"
+ transactionToString(transaction, mTransactionHandler));
return;
}
}
}
// 执行事务的回调 -- 第 8 小节中添加到 ClientTransaction 中的回调 -- LaunchActivityItem
executeCallbacks(transaction);
// 执行生命周期状态
executeLifecycleState(transaction);
mPendingActions.clear();
}
/**
* Cycle through all states requested by callbacks and execute them at proper times.
* 循环遍历回调列表中的所有状态请求,在适当的时间执行它们
*/
@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;
// Index of the last callback that requests some post-execution state.
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);
}
// 获取到 LaunchActivityItem 并调用其 execute() 方法
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() 方法中,循环遍历回调列表中的所有状态请求,并在适当的时间执行添加的状态请求,这里即 8. 获取 ClientTransaction、添加 Callback、设置 LifecycleStateRequest 中添加到 ClientTransaction 中的 LaunchActivityItem。
2.5.14 LaunchActivityItem 请求启动 Activity
/**
1. Request to launch an activity.
2. 请求启动 Activity
3. @hide
*/
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 /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
}
ClientTransactionHandler 是一个抽象类,ActivityThread 继承自 ClientTransactionHandler 并实现了其抽象方法,所以这里又回到了 ActivityThread 类,调用其 handleLaunchActivity() 方法来启动 Activity。
2.5.15 ActivityThread 执行启动 Activity 事务
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
......
WindowManagerGlobal.initialize();
// Hint the GraphicsEnvironment that an activity is launching on the process.
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 {
// 启动 Activity 发生异常,不论是什么原因,通知 ATMS 终止此 Activity
try {
ActivityTaskManager.getService()
.finishActivity(r.token, Activity.RESULT_CANCELED, null,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
return a;
}
/** Core implementation of activity launch. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
......
// 创建 Activity 的 Context
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
// 通过 ClassLoader 反射获取 Activity 的实例
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
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、初始化 Window 等
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;
// 执行 Activity 的 onCreate
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());
}
// 设置生命周期的状态为 ON_CREATE
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() 方法,Activity # performCreate() 方法中调用 Activity # onCreate() 方法。
流程走到这里 Activity # onCreate() 方法执行完,并设置生命周期的状态为 ON_CREATE,还有 onStart、onResume 等生命周期方法呢?
2.5.16 ActivityThread 执行生命周期事务
回看 13. TransactionExecutor 事务转换执行器,之前我们只分析了 TransactionExecutor # executeCallbacks(transaction) 执行回调有关的流程,现在我们来看一下 TransactionExecutor # executeLifecycleState(transaction) 方法。
/** Transition to the final state if requested by the transaction. */
private void executeLifecycleState(ClientTransaction transaction) {
// 获取之前设置的生命周期状态请求
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
if (lifecycleItem == null) {
// No lifecycle request, return early.
return;
}
final IBinder token = transaction.getActivityToken();
// 获取 ActivityClientRecord,该对象保存 Activity 的启动信息
final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
......
if (r == null) {
// Ignore requests for non-existent client records for now.
return;
}
// Cycle to the state right before the final requested state.
// 执行当前已设置的生命周期请求最终状态之前的状态
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);
// Execute the final transition with proper parameters.
// 执行设置的生命周期事务的最终转换
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
TransactionExecutor # executeLifecycleState(transaction) 方法主要是用来转换 Activity 的生命周期状态至设置的最终状态并执行,流程如下:
获取 8. 获取 ClientTransaction、添加 Callback、设置 LifecycleStateRequest 中设置的执行 transaction 后的最终的生命周期状态请求,也就是设置的 ResumeActivityItem。
获取保存 Activity 启动信息的 ActivityRecord 对象,调用 cycleToPath() 方法获取并执行设置的生命周期请求最终状态之前的状态。
调用 ActivityLifecycleItem # execute() 方法执行设置的生命周期事务的最终转换,这里实际调用的是 ResumeActivityItem # execute() 方法。
2.5.17 TransactionExecutor 执行中间态生命周期请求事务
何为中间态生命周期请求事务? Android 系统针对 Activity 的生命周期,定义了与之相对应的 XXXActivityItem 类,如 StartActivityItem、PauseActivityItem 等,即为处于中间态的生命周期请求事务。
那这些中间态的生命周期请求事务什么时候会被执行呢?如 StartActivityItem 对应的 Activity 的生命周期请求 onStart 是在何时触发的呢?
private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
ClientTransaction transaction) {
final int start = r.getLifecycleState();
......
final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
performLifecycleSequence(r, path, transaction);
}
/** Transition the client through previously initialized state sequence. */
private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
ClientTransaction transaction) {
final int size = path.size();
for (int i = 0, state; i < size; i++) {
state = path.get(i);
.......
switch (state) {
case ON_CREATE:
mTransactionHandler.handleLaunchActivity(r, mPendingActions,
null /* customIntent */);
break;
case ON_START:
mTransactionHandler.handleStartActivity(r.token, mPendingActions);
break;
......
}
}
}
方法的执行流程如下:
获取待启动 Activity 当前的生命周期状态,由于 Activity # onCreate() 方法执行完,并设置生命周期的状态为 ON_CREATE,所以 start 为 ON_CREATE。在上一节中我们知道设置的最终的生命周期状态请求是 ResumeActivityItem,其 getTargetState() 方法返回的是 ON_RESUME。
通过 TransactionExecutorHelper 对象调用其 getLifecyclePath() 方法,获取此次要执行生命周期的路径,方法中根据 start 和 finish 状态来构造一个 IntArray 类型的状态数组。
调用 TransactionExecutor # performLifecycleSequence() 方法中,遍历构建的状态序列执行应用进程中对应的 ActivityThread # handleXXXActivity() 方法完成生命周期状态的转换。
看到这里,还是未明确找到 Activity 生命周期的 onStart 在何时、何地执行的?但是 TransactionExecutorHelper 这个辅助类值得关注,通过 TransactionExecutorHelper # getLifecyclePath() 方法来获取此次要执行生命周期的路径,看看这个方法怎么做的?
2.5.18 TransactionExecutorHelper 获取待执行生命周期的状态序列
先看一下 ON_START、ON_RESUME 等这些生命周期状态的定义,方便我们理解后续流程。
/**
* 请求 Activity 应该达到的生命周期状态
*/
public abstract class ActivityLifecycleItem extends ClientTransactionItem {
......
@Retention(RetentionPolicy.SOURCE)
public @interface LifecycleState{}
public static final int UNDEFINED = -1;
public static final int PRE_ON_CREATE = 0;
public static final int ON_CREATE = 1;
public static final int ON_START = 2;
public static final int ON_RESUME = 3;
public static final int ON_PAUSE = 4;
public static final int ON_STOP = 5;
public static final int ON_DESTROY = 6;
public static final int ON_RESTART = 7;
/** A final lifecycle state that an activity should reach. */
@LifecycleState
public abstract int getTargetState();
}
与 Activity 生命周期有关的 StartActivityItem、ResumeActivityItem 等继承自该抽象类并实现其抽象方法 getTargetState(),方法中返回对应的生命周期,注意:LaunchActivityItem 直接继承自 ClientTransactionItem。
结合上面这个抽象类来分析 TransactionExecutorHelper # getLifecyclePath() 方法,代码如下:
@VisibleForTesting
public IntArray getLifecyclePath(int start, int finish, boolean excludeLastState) {
......
// 清空生命周期状态序列
mLifecycleSequence.clear();
if (finish >= start) {
if (start == ON_START && finish == ON_STOP) {
// 如果很快从 ON_START 转换到 ON_STOP 状态,此时不需要经历恢复、暂停状态
mLifecycleSequence.add(ON_STOP);
} else {
// 添加 start 到 finish 之间的生命周期状态
for (int i = start + 1; i <= finish; i++) {
mLifecycleSequence.add(i);
}
}
}
......
// 根据条件判断移除最后的生命周期状态
if (excludeLastState && mLifecycleSequence.size() != 0) {
mLifecycleSequence.remove(mLifecycleSequence.size() - 1);
}
return mLifecycleSequence;
}
经过之前的分析,可知 TransactionExecutorHelper # getLifecyclePath() 方法中传入的 start 为 ON_CREATE,finish 为 ON_RESUME,excludeLastState 为 true。由 ActivityLifecycleItem 抽象类定义可知 finish >= start,因此方法中可以只关注这部分的逻辑处理,通过比较可以发现 ON_CREATE 和 ON_RESUME 中间还有 ON_START 这个中间状态,所以在 mLifecycleSequence 状态序列中将添加 ON_START 和 ON_RESUME 状态,此时因为 excludeLastState 为 true,所以最后会移除掉 ON_RESUME 状态,故返回的状态序列中只包含 ON_START 状态,即 cycleToPath() 方法中获得的 path 中只包含 ON_START 状态。
所以此时,回到 17. TransactionExecutor 执行中间态生命周期请求事务 分析 performLifecycleSequence() 方法,此时遍历构建的状态序列中只有 ON_START 状态值,因此执行应用进程中对应的 ActivityThread # handleStartActivity() 方法完成生命周期状态的转换,方法调用流程如下:
ActivityThread # handleStartActivity() 方法中调用 activity # performStart() 方法,设置生命周期的状态为 ON_START。
Activity # performStart() 方法中调用 Instrumentation # callActivityOnStart() 方法,Instrumentation # callActivityOnStart() 方法中调用 Activity # onStart() 方法。
流程走到这里 Activity # onStart() 方法执行完,并设置生命周期的状态为 ON_START,继续分析 onResume 生命周期方法的调用过程?
2.5.19 TransactionExecutor 执行生命周期事务的最终转换
回看 ActivityThread 执行生命周期事务 中,最后会执行已设置的生命周期事务的最终转换,通过前面的分析,这里执行的是 ResumeActivityItem # execute() 方法,代码如下:
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
"RESUME_ACTIVITY");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
上面分析过 ClientTransactionHandler 是一个抽象类,ActivityThread 继承自 ClientTransactionHandler 并实现了其抽象方法,所以这里调用的是 ActivityThread # handleResumeActivity() 方法,不在贴源码,方法调用流程如下:
ActivityThread # handleResumeActivity() 方法调用 ActivityThread # performResumeActivity() 方法,设置生命周期的状态为 ON_RESUME。
ActivityThread # performResumeActivity() 方法调用 Activity # performResume() 方法。Activity # performResume() 方法中调用 Instrumentation # callActivityOnResume() 方法,Instrumentation # callActivityOnResume() 方法中调用 Activity # onResume() 方法。
断点后,可查看调用关系如下,
三,总结
至此,基于 Android R(11.0)我们终于解析完 Activity 的启动过程,本篇主要是分析从桌面点击应用ICON启动Activity 的启动流程,去掉本篇中关于启动进程 Launcher、孵化进程 Zygote 等有关的篇幅,也即普通 Activity 的启动过程,这里不再单独分析。
此外,有关 ClientTransaction 部分值得深入学习,这是 Android P(9.0)加入的,其作用如下:
减少通信次数:系统进程中 AMS 到应用进程,一次通信,包含各种通信事件和内容。
统筹消息域:将生命周期变化与事件更新分类统筹,分别处理。
减少两端耦合:系统进程中 AMS 对于生命周期的发送要求,与应用进程对生命周期的处理需求并不对等,所以应用进程会自己组装完整的生命周期回调,处理逻辑更内聚。
————————————————
参考:CSDN博主「neuHenry」的原创文章,遵循CC 4.0 BY-SA版权协议
原文链接:https://blog.csdn.net/u010347226/article/details/124890884