❤️ Android startActivity源码分析(含启动新应用) ❤️
作者:互联网
目录
3.2 IActivityTaskManagerSingleton
4、ActivityTaskManagerService.java
4.3 startActivityAsUser() 比上面多个参数
4.4 getActivityStartController()
5、ActivityStartController.java
7.1 resumeFocusedTasksTopActivities()
8.1 resumeTopActivityUncheckedLocked()
8.2 resumeTopActivityInnerLocked()
9、ActivityTaskSupervisor.class
9.2.1 realStartActivityLocked()
9.2.2 ClientLifecycleManager.scheduleTransaction()
9.2.3 ClientTransaction.schedule()
9.2.4 ApplicationThread.scheduleTransaction()
9.2.5 ClientTransactionHandler.scheduleTransaction()
9.2.6 ActivityThread.H.handleMessage()
9.2.7 TransactionExecutor.execute()
9.2.8 TransactionExecutor.executeCallbacks()
9.2.9 TransactionExecutor.cycleToPath()
9.2.10 TransactionExecutor.performLifecycleSequence()
9.2.11 ClientTransactionHandler.handleLaunchActivity()
9.2.12 ActivityThread.handleLaunchActivity()
9.2.13 ActivityThread.performLaunchActivity()
9.2.14 Instrumentation.newActivity()
9.2.15 Instrumentation.callActivityOnCreate()
9.3.1 ATMS.startProcessAsync()
9.3.2 ActivityManagerInternal.startProcess()
9.3.3 ActivityManagerService.LocalService.startProcess()
9.3.4 ActivityManagerService.startProcessLocked()
9.3.5 ProcessList.startProcessLocked()
9.3.6 ProcessList.startProcess()
9.3.9 ZygoteProcess.startViaZygote()
9.3.10 ZygoteProcess.openZygoteSocketIfNeeded(abi)
9.4.11 ZygoteProcess.zygoteSendArgsAndGetResult()
9.4.12 ZygoteProcess.attemptZygoteSendArgsAndGetResult()
9.4.14 ZygoteService.runSelectLoop()
9.4.15 ZygoteConnection.processOneCommand()
开局一张图
源码版本:Android 11(SDK 30)
涉及到的类
-
Instrumentation:负责 Application 和 Activity 的建立和生命周期控制。
-
ActivityTaskManager:此类提供有关Activity及其容器(如任务、堆栈和显示)的信息并与之交互。
-
ActivityTaskManagerService:用于管理Activity及其容器(任务、显示等)的系统服务。之前这个活是AMS的,现在从AMS中剥离出来了。
-
ActivityStartController:用于委托Activity启动的控制器。
-
ActivityStarter:专门负责一个 Activity 的启动操做。它的主要做用包括解析 Intent、建立 ActivityRecord、若是有可能还要建立 TaskRecordflex
-
ActivityStack:Activity在ATMS的栈管理,用来记录已经启动的Activity的先后关系,状态信息等。通过ActivityStack决定是否需要启动新的进程。
-
RootWindowContainer:设备的Root WindowContainer。
-
TaskRecord:ATMS抽象出来的一个"任务"的概念,是记录ActivityRecord的栈,一个"Task"包含若干个ActivityRecord。ATMS用TaskRecord确保Activity启动和退出的顺序。
-
ActivityStackSupervisor:负责所有Activity栈的管理。内部管理了mHomeStack、mFocusedStack和mLastFocusedStack三个Activity栈。其中,mHomeStack管理的是Launcher相关的Activity栈;mFocusedStack管理的是当前显示在前台Activity的Activity栈;mLastFocusedStack管理的是上一次显示在前台Activity的Activity栈。
-
ActivitySupervisor:管理 activity 任务栈。
-
ActivityThread:ActivityThread 运行在UI线程(主线程),App的真正入口。
-
ApplicationThread:用来实现ATMS和ActivityThread之间的交互。
-
ApplicationThreadProxy:ApplicationThread 在服务端的代理。ATMS就是通过该代理与ActivityThread进行通信的。
-
ClientLifecycleManager:能够组合多个客户端生命周期 transaction 请求和/或回调,并将它们作为单个 transaction 执行。
-
TransactionExecutor:已正确的顺序管理 transaction 执行的类。
1、Activity.java
1.1 startActivity()
@Override
public void startActivity(Intent intent) {
//接着往里看
this.startActivity(intent, null);
}
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
...
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
最终调用了 startActivityForResult 方法,传入的 -1 表示不需要获取 startActivity 的结果。
1.2 startActivityForResult()
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
//mParent表示当前Activitiy的父类,
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
//ActivityThread mMainThread;
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
...
} else {
...
}
}
startActivityForResult 调用 Instrumentation.execStartActivity 方法。剩下的交给 Instrumentation 类去处理。
mMainThread 是 ActivityThread 类型,ActivityThread 可以理解为一个进程,这就是 Activity 所在的进程。
通过 mMainThread 获取一个 ApplicationThread 的引用,这个引用就是用来实现进程间通信的,具体来说就是 AMS 所在系统进程通知应用程序进程进行的一系列操作。
上面有Instrumentation、ActivityThread、ApplicationThread 等类的介绍。
2、Instrumentation.java
frameworks/base/core/java/android/app/Instrumentation.java
/**
* Base class for implementing application instrumentation code.
*/
public class Instrumentation {
...
}
2.1 execStartActivity()
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityTaskManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
//检查启动Activity的结果
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
在 Instrumentation 中,调用了 ActivityTaskManager.getService().startActivity() 。咱们近距离观望一下。
3、ActivityTaskManage.java
frameworks/base/core/java/android/app/ActivityTaskManager.java
@TestApi
@SystemService(Context.ACTIVITY_TASK_SERVICE)
public class ActivityTaskManager {
...
}
3.1 getService()
/** @hide */
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
3.2 IActivityTaskManagerSingleton
@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);
}
};
这里实际上返回的是一个 ActivityTaskManagerService 这出现了跨进程 (从应用进程(app) > system_service进程) ,然后调用其 startActivity 方法。
实际上这里就是通过 AIDL 来调用 ATMS 的 startActivity 方法,返回 IActivityTaskManager.startActivity 的结果:Activity 已正常成功启动。
至此,startActivity 的工作重心成功地从 应用进程(app) 转移到了系统进程(system_service) 的 ATMS 中。
4、ActivityTaskManagerService.java
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
...
}
4.1 startActivity()
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
4.2 startActivityAsUser()
@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*/);
}
4.3 startActivityAsUser() 比上面多个参数
//重点来了
private int startActivityAsUser(IApplicationThread caller, String callingPackage,
@Nullable String callingFeatureId, Intent intent, String resolvedType,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
assertPackageMatchesCallingUid(callingPackage);
enforceNotIsolatedCaller("startActivityAsUser");
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// 在此处切换到用户app堆栈。
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();
}
4.4 getActivityStartController()
ActivityStartController getActivityStartController() {
return mActivityStartController;
}
5、ActivityStartController.java
/**
* Controller for delegating activity launches.
*/
public class ActivityStartController {
...
}
5.1 obtainStarter();
/**
* @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);
}
6、ActivityStarter.java
frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
/**
* Controller for interpreting how and then launching an activity.
*
* This class collects all the logic for determining how an intent and flags should be turned into
* an activity and associated task and stack.
*/
class ActivityStarter {
...
}
6.1 execute()
/**
* 根据前面提供的请求参数解析必要的信息,执行开始活动的请求。
* @return The starter result.
*/
int execute() {
...
res = executeRequest(mRequest);
...
}
6.2 executeRequest()
/**
* Activity启动之前需要做那些准备?
* 通常的Activity启动流程将通过 startActivityUnchecked 到 startActivityInner。
*/
private int executeRequest(Request request) {
...
//Activity的记录
ActivityRecord sourceRecord = null;
ActivityRecord resultRecord = null;
...
//Activity stack(栈)管理
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
restrictedBgActivity, intentGrants);
...
return mLastStartActivityResult;
}
从上面代码可以看出,经过多个方法的调用,最终通过 obtainStarter 方法获取了 ActivityStarter 类型的对象,然后调用其 execute() 方法。
在 execute() 方法中,会再次调用其内部的 executeRequest() 方法。
咱们接着看看 startActivityUnchecked() ;
6.3 startActivityUnchecked()
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
boolean restrictedBgActivity, NeededUriGrants intentGrants) {
....
try {
...
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
} finally {
...
}
postStartActivityProcessing(r, result, startedActivityRootTask);
return result;
}
6.4 startActivityInner()
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
boolean restrictedBgActivity, NeededUriGrants intentGrants) {
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
voiceInteractor, restrictedBgActivity);
//计算启动模式
computeLaunchingTaskFlags();
computeSourceRootTask();
//设置启动模式
mIntent.setFlags(mLaunchFlags);
...
// 关键点来了
mRootWindowContainer.resumeFocusedTasksTopActivities(
mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
...
return START_SUCCESS;
}
这个是 mRootWindowContainer 是 RootWindowContainer。
7、RootWindowContainer.java
frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
/** Root {@link WindowContainer} for the device. */
class RootWindowContainer extends WindowContainer<DisplayContent>
implements DisplayManager.DisplayListener {
...
}
7.1 resumeFocusedTasksTopActivities()
boolean resumeFocusedTasksTopActivities(
Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
boolean deferPause) {
...
boolean result = false;
if (targetRootTask != null && (targetRootTask.isTopRootTaskInDisplayArea()
|| getTopDisplayFocusedRootTask() == targetRootTask)) {
result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions,
deferPause);
}
...
return result;
}
当然这里看的是 targetRootTask 是 Task 对象的实例。咱们就去追踪这个方法。
8、Task.java
frameworks/base/services/core/java/com/android/server/wm/Task.java
class Task extends WindowContainer<WindowContainer> {
...
}
8.1 resumeTopActivityUncheckedLocked()
@GuardedBy("mService")
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
...
someActivityResumed = resumeTopActivityInnerLocked(prev, options, deferPause);
...
return someActivityResumed;
}
8.2 resumeTopActivityInnerLocked()
@GuardedBy("mService")
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
...
try {
....
} catch (Exception e) {
....
//重点
mTaskSupervisor.startSpecificActivity(next, true, false);
return true;
}
....
return true;
}
mTaskSupervisor:是 ActivityTaskSupervisor 对象的实例。下面咱们看看其 startSpecificActivity() 方法。
9、ActivityTaskSupervisor.class
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
...
}
9.1 startSpecificActivity()
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
// 此 Activity 的 应用程序(进程) 是否已在运行?
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;
if (wpc != null && wpc.hasThread()) {
try {
//进程已启动
//注释1:开始启动activity
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
}
}
r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
final boolean isTop = andResume && r.isTopRunningActivity();
//注释2:进程未启动
mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
}
注释1:进程已启动。
注释2:进程未启动。
9.2 进程已启动
9.2.1 realStartActivityLocked()
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
...
//创建 Activity 启动的 transaction
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);
final boolean isTransitionForward = r.isTransitionForward();
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
r.takeOptions(), isTransitionForward,
proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
r.createFixedRotationAdjustmentsIfNeeded(), r.shareableActivityToken,
r.getLaunchedFromBubble()));
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
...
return true;
}
这的 mService 就是 ActivityTaskManagerService(ATMS) 的实例。mService.getLifecycleManager() 返回的是一个 ClientLifecycleManager 对象。想看 scheduleTransaction() 是干嘛的 只能找它了。
9.2.2 ClientLifecycleManager.scheduleTransaction()
frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
//这里咱们传入的是一个启动 Activity 的 transaction
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
//注释1
transaction.schedule();
if (!(client instanceof Binder)) {
// 如果 client 不是Binder的实例,则它是一个远程调用,此时可以安全地回收该对象。
// 在ActivityThread中的客户端上执行transaction后,将回收用于本地调用的所有对象。
transaction.recycle();
}
}
从方法中看出 transaction 是个 ClientTransaction 。那咱直接去找他。
9.2.3 ClientTransaction.schedule()
/** Target client. */
private IApplicationThread mClient;
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
看到 IApplicationThread ,咱们直接去找 ApplicationThread 。
9.2.4 ApplicationThread.scheduleTransaction()
frameworks/base/core/java/android/app/ActivityThread.java
ApplicationThread 属于 ActivityThread 的内部类。
public final class ActivityThread extends ClientTransactionHandler
implements ActivityThreadInternal {
...
private class ApplicationThread extends IApplicationThread.Stub {
...
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
...
}
...
}
ActivityThread 类中是没有 scheduleTransaction 方法的,通常遇到这种状况,直接找其父类 ClientTransactionHandler。
9.2.5 ClientTransactionHandler.scheduleTransaction()
frameworks/base/core/java/android/app/ClientTransactionHandler.java
public abstract class ClientTransactionHandler {
/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
}
从这里看到 他调用 sendMessage() 方法发送了个 ActivityThread.H.EXECUTE_TRANSACTION 消息,咱们回到其子类 ActivityThread 中查看。
9.2.6 ActivityThread.H.handleMessage()
这里的 H 是 ActivityThread 的 内部类。
// An executor that performs multi-step transactions.
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
class H extends Handler {
public void handleMessage(Message msg) {
switch (msg.what) {
...
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
if (isSystem()) {
transaction.recycle();
}
break;
...
}
}
}
这里的 mTransactionExecutor 是 transactions 的执行者。
9.2.7 TransactionExecutor.execute()
frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
public void execute(ClientTransaction transaction) {
...
executeCallbacks(transaction);
...
}
9.2.8 TransactionExecutor.executeCallbacks()
/** 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();
...
final IBinder token = transaction.getActivityToken();
ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
...
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
...
if (postExecutionState != UNDEFINED && r != null) {
// 重点
final boolean shouldExcludeLastTransition =
i == lastCallbackRequestingState && finalState == postExecutionState;
cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
}
}
}
这个方法的重点是 cycleToPath() ,咱们继续。
9.2.9 TransactionExecutor.cycleToPath()
private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
ClientTransaction transaction) {
final int start = r.getLifecycleState();
//IntArray:实现不断增长的int基元数组。
//获取此次要执行生命周期的路径path
final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
performLifecycleSequence(r, path, transaction);
}
9.2.10 TransactionExecutor.performLifecycleSequence()
/** 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, mPendingActions,
null /* activityOptions */);
break;
case ON_RESUME:
mTransactionHandler.handleResumeActivity(r, false /* finalStateRequest */,
r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
break;
case ON_PAUSE:
mTransactionHandler.handlePauseActivity(r, false /* finished */,
false /* userLeaving */, 0 /* configChanges */, mPendingActions,
"LIFECYCLER_PAUSE_ACTIVITY");
break;
case ON_STOP:
mTransactionHandler.handleStopActivity(r, 0 /* configChanges */,
mPendingActions, false /* finalStateRequest */,
"LIFECYCLER_STOP_ACTIVITY");
break;
case ON_DESTROY:
mTransactionHandler.handleDestroyActivity(r, false /* finishing */,
0 /* configChanges */, false /* getNonConfigInstance */,
"performLifecycleSequence. cycling to:" + path.get(size - 1));
break;
case ON_RESTART:
mTransactionHandler.performRestartActivity(r, false /* start */);
break;
default:
throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
}
}
}
到这里咱们终于看到了熟悉的内容,Activity的生命周期,好激动哈哈。
这里咱们以 ON_CREATE 为例。从上面代码看出 ON_CREATE 等其实就是个int值(常量),这里咱就不多描述了。mTransactionHandler 是 ClientTransactionHandler 的实例,直接看handleLaunchActivity() 方法。
9.2.11 ClientTransactionHandler.handleLaunchActivity()
frameworks/base/core/java/android/app/ClientTransactionHandler.java
public abstract class ClientTransactionHandler {
...
/** Perform activity launch. */
public abstract Activity handleLaunchActivity(@NonNull ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent);
...
}
从上面看出 handleLaunchActivity() 是抽象方法,ActivityThread 做为其子类,只能找其子类 ActivityThread 看看具体实现。
9.2.12 ActivityThread.handleLaunchActivity()
/**
* Extended implementation of activity launch. Used when server requests a launch or relaunch.
*/
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
// 在创建 activity 之前初始化
if (ThreadedRenderer.sRendererEnabled
&& (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
HardwareRenderer.preload();
}
//初始化 Activity 的 WindowManager,每一个 Activity 都会对应一个"窗口"。
WindowManagerGlobal.initialize();
// 提示 GraphicsEnvironment Activity 正在进程中启动。
GraphicsEnvironment.hintActivityLaunch();
//这里重点:Activity 启动的核心实现。
final Activity a = performLaunchActivity(r, customIntent);
...
return a;
}
performLaunchActivity(),Activity 启动的核心实现。具体咱们往下看
9.2.13 ActivityThread.performLaunchActivity()
/** Core implementation of activity launch. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
//注释1: 新实例化的 Activity 对象。
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
...
} catch (Exception e) {
...
}
//重点:调用activity.attach()。
//建立 Activity 与 Context 之间的联系。
//创建 PhoneWindow 对象,并与 Activity 进行关联操作。
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback,
r.assistToken, r.shareableActivityToken);
//persistableMode属性设置为: ActivityInfo.PERSIST_ACROSS_REBOOTS(persistAcrossReboots);
//注释2:执行 Activity 的 onCreate() 方法。
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
return activity;
}
这里首先看看 mInstrumentation 其实就是 Instrumentation 。 在本文 startActivityForResult 部分也有用到。Instrumentation 负责 Application 和 Activity 的建立和生命周期控制。
这里用到了他的两个方法咱们一起看看。
9.2.14 Instrumentation.newActivity()
/**
* @param cl 用于实例化对象的类加载器(ClassLoader)。
* @param className 实现 Activity 对象的类的名称。
* @param intent 指定要实例化的活动类的 Intent 对象。
*
* @return 新实例化的 Activity 对象。
*/
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
String pkg = intent != null && intent.getComponent() != null
? intent.getComponent().getPackageName() : null;
return getFactory(pkg).instantiateActivity(cl, className, intent);
}
pkg 就是 intent 所在的包名。
getFactory(pkg) 通过获取到的包名 得到 AppComponentFactory 。然后调用其 instantiateActivity() 方法获取 Activity 。
9.2.14.1 Instrumentation.getFactory()
private AppComponentFactory getFactory(String pkg) {
if (pkg == null) {
...
return AppComponentFactory.DEFAULT;
}
if (mThread == null) {
....
return AppComponentFactory.DEFAULT;
}
LoadedApk apk = mThread.peekPackageInfo(pkg, true);
// This is in the case of starting up "android".
if (apk == null) apk = mThread.getSystemContext().mPackageInfo;
return apk.getAppFactory();
}
9.2.14.2 AppComponentFactory.instantiateActivity()
frameworks/base/core/java/android/app/AppComponentFactory.java
/**
* 用于控制 manifest 元素实例化的接口。
*
* @see #instantiateApplication
* @see #instantiateActivity
* @see #instantiateClassLoader
* @see #instantiateService
* @see #instantiateReceiver
* @see #instantiateProvider
*/
public class AppComponentFactory {
...
}
instantiateActivity()
/**
* 此方法仅用于提供用于实例化的钩子。
* 它不提供对 Activity 对象的早期访问。
* 返回的对象还不会被初始化为 Context 并且不应该用于与其他 android API 交互。
*/
public @NonNull Activity instantiateActivity(@NonNull ClassLoader cl, @NonNull String className,
@Nullable Intent intent)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (Activity) cl.loadClass(className).newInstance();
}
这里通过反射拿到 Activity 的实例。
9.2.15 Instrumentation.callActivityOnCreate()
/**
* 执行 Activity#onCreate方法的调用。
*
* @param activity 正在创建的 activity 。
* @param icicle 将以前冻结的状态(或null)传递给 onCreate() 。
*/
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
//重点
activity.performCreate(icicle);
postPerformCreate(activity);
}
从这里可以看到即将进入 Activity 的内部。
9.2.15.1 Activity.performCreate()
final void performCreate(Bundle icicle) {
performCreate(icicle, null);
}
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
...
//重点
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
...
}
看到这里,startSpecificActivity() 方法中的 进程已启动的状态算是完结。startActivity 启动成功。结合 9.2.13 ActivityThread.performLaunchActivity() 查看 Activity 中的 attach() 方法调用早于 onCreate() 方法。
下面让我们回到 9.1 startSpecificActivity() 中查看进程未启动的流程情况。
9.3 进程未启动
既然进程未启动那肯定先启动进程了。咱们接着看。
final ActivityTaskManagerService mService;
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
....
mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
}
从这里看到 mService 其实就是 ATMS ,走着。
9.3.1 ATMS.startProcessAsync()
void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
String hostingType) {
try {
...
// 发布消息以启动进程,以避免在持有 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);
}
}
9.3.2 ActivityManagerInternal.startProcess()
frameworks/base/core/java/android/app/ActivityManagerInternal.java
/**
* Activity manager local system service interface.
*/
public abstract class ActivityManagerInternal {
/** Starts a given process. */
public abstract void startProcess(String processName, ApplicationInfo info,
boolean knownToBeDead, boolean isTop, String hostingType, ComponentName hostingName);
}
这里是个抽象类,咱们去找其实现类 ActivityManagerService.LocalService。
9.3.3 ActivityManagerService.LocalService.startProcess()
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback, ActivityManagerGlobalLock {
...
@VisibleForTesting
public final class LocalService extends ActivityManagerInternal
implements ActivityManagerLocal {
...
@Override
public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
boolean isTop, String hostingType, ComponentName hostingName) {
try {
synchronized (ActivityManagerService.this) {
// 如果该进程称为top app,请设置一个提示,以便在启动该进程时,可以立即应用最高优先级,以避免在附加top app进程之前cpu被其他进程抢占。
startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
new HostingRecord(hostingType, hostingName, isTop),
ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
false /* isolated */);
}
} finally {
}
}
}
}
9.3.4 ActivityManagerService.startProcessLocked()
/**
* Process management.
*/
final ProcessList mProcessList;
@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 */);
}
可以看出,这里的 mProcessList 就是 ProcessList。
9.3.5 ProcessList.startProcessLocked()
frameworks/base/services/core/java/com/android/server/am/ProcessList.java
@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) {
...
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) {
...
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) {
...
//终于到重点了。
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);
...
}
反复调用,终于看到了关键代码 startProcess() 。
9.3.6 ProcessList.startProcess()
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) {
...
final Process.ProcessStartResult startResult;
if (hostingRecord.usesWebviewZygote()) {
//进程是否应该从 webview zygote 产生
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()) {
//进程是否应该从应用程序 zygote 中产生
final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
// 我们无法隔离应用程序数据和存储数据,因为父 zygote 已经这样做了。
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});
}
...
}
无论那种情况都会调用 Process.start() ;
9.3.7 Process.start()
frameworks/base/core/java/android/os/Process.java
/**
* State associated with the zygote process.
*/
public static final ZygoteProcess ZYGOTE_PROCESS = new ZygoteProcess();
public static ProcessStartResult start(@NonNull final String processClass,
@Nullable final String niceName,
int uid, int gid, @Nullable int[] gids,
int runtimeFlags,
int mountExternal,
int targetSdkVersion,
@Nullable String seInfo,
@NonNull String abi,
@Nullable String instructionSet,
@Nullable String appDataDir,
@Nullable String invokeWith,
@Nullable String packageName,
int zygotePolicyFlags,
boolean isTopApp,
@Nullable long[] disabledCompatChanges,
@Nullable Map<String, Pair<String, Long>>
pkgDataInfoMap,
@Nullable Map<String, Pair<String, Long>>
whitelistedDataInfoMap,
boolean bindMountAppsData,
boolean bindMountAppStorageDirs,
@Nullable String[] zygoteArgs) {
return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, packageName,
zygotePolicyFlags, isTopApp, disabledCompatChanges,
pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,
bindMountAppStorageDirs, zygoteArgs);
}
这里的 ZYGOTE_PROCESS 就是 ZygoteProcess 。调用其 start() 方法。
9.3.8 ZygoteProcess.start()
frameworks/base/core/java/android/os/ZygoteProcess.java
/**
* 开始一个新的进程。
* 如果启用了进程,则会创建一个新进程并在那里执行processClass 的静态main() 函数。
* 该函数返回后进程将继续运行。
*
* 如果未启用进程,则会在调用者进程中创建一个新线程并在那里调用 processclass 的 main()。
*
* niceName 参数,如果不是空字符串,则是一个自定义名称,用于提供给进程而不是使用 processClass。
* 这允许您创建易于识别的进程,即使您使用相同的基本 processClass 来启动它们。
*
* 当 invokeWith 不为 null 时,进程将作为一个新的 app 而不是 zygote fork 启动。
* 请注意,这仅适用于 uid 0 或当runtimeFlags 包含 DEBUG_ENABLE_DEBUGGER 时。
*
* @param processClass 用作进程主入口点的类。
* @param niceName 用于进程的更易读的名称。
* @param uid 进程将在其下运行的用户 ID。
* @param gid 进程将在其下运行的组 ID。
* @param gids 与进程关联的附加组 ID。
* @param runtimeFlags 附加标志。
* @param targetSdkVersion 应用的目标 SDK 版本。
* @param seInfo null-ok 新进程的 SELinux 信息。
* @param abi 非空此应用程序应使用的 ABI。
* @param instructionsSet null-确定要使用的指令集。
* @param appDataDir null-ok 应用程序的数据目录。
* @param invokeWith null-ok 要调用的命令。
* @param packageName null-ok 这个进程所属的包名。
* @param zygotePolicyFlags 用于确定如何启动应用程序的标志。
* @param isTopApp 进程是否为高优先级应用程序启动。
* @param disabledCompatChanges 正在启动的进程的禁用兼容更改的 null-ok 列表。
* @param pkgDataInfoMap 从相关包名称映射到私有数据目录卷 UUID 和 inode 编号。
* @param allowlistedDataInfoList 从允许的包名称映射到私有数据目录卷 UUID 和 inode 编号。
* @param bindMountAppsData zygote 是否需要挂载 CE 和 DE 数据。
* @param bindMountAppStorageDirs zygote 是否需要挂载Android/obb 和Android/data。
*
* @param zygoteArgs 提供给 Zygote 进程的附加参数。
* @return 一个对象,描述尝试启动进程的结果。
* @throws RuntimeException 出现致命启动失败
*/
//这里从上一个方法传来一大堆参数就不多描述了
public final Process.ProcessStartResult start(...) {
...
return startViaZygote(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges,
pkgDataInfoMap, allowlistedDataInfoList, bindMountAppsData,
bindMountAppStorageDirs, zygoteArgs);
...
}
9.3.9 ZygoteProcess.startViaZygote()
//这里从上一个方法传来一大堆参数就不多描述了
private Process.ProcessStartResult startViaZygote(...)
throws ZygoteStartFailedEx {
...
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.
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
zygotePolicyFlags,
argsForZygote);
}
}
在看 zygoteSendArgsAndGetResult() 之前咱们看看 openZygoteSocketIfNeeded(abi) 。
9.3.10 ZygoteProcess.openZygoteSocketIfNeeded()
/**
* 尝试打开一个 session socket到具有兼容 ABI 的 Zygote 进程(如果尚未打开)。 如果兼容的 session socket已经打开,则返回该 session socket。
*
* 此功能可能会阻塞,并且可能必须尝试连接到多个 Zygotes 才能找到合适的 Zygotes。 需要保持 mLock。
*/
@GuardedBy("mLock")
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
try {
attemptConnectionToPrimaryZygote();
...
}
------------分割线-------------
/**
* 如果Primary Zygote不存在或已断开连接,则为它创建一个 ZygoteState。
*/
@GuardedBy("mLock")
private void attemptConnectionToPrimaryZygote() throws IOException {
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
primaryZygoteState =
ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);
...
}
}
------------分割线-------------
static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress,
@Nullable LocalSocketAddress usapSocketAddress)
throws IOException {
...
//创建LocalSocket
final LocalSocket zygoteSessionSocket = new LocalSocket();
//将zygoteSessionSocket连接到端点。
//只能在尚未连接的实例上调用。
zygoteSessionSocket.connect(zygoteSocketAddress);
...
}
打开了 ZygoteSocket 之后咱们看看 zygoteSendArgsAndGetResult();
9.4.11 ZygoteProcess.zygoteSendArgsAndGetResult()
@GuardedBy("mLock")
private Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList<String> args)
throws ZygoteStartFailedEx {
...
String msgStr = args.size() + "\n" + String.join("\n", args) + "\n";
return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
}
9.4.12 ZygoteProcess.attemptZygoteSendArgsAndGetResult()
private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
try {
final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
//写,调用zygote(ZygoteInit)。
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);
}
}
9.4.13 ZygoteInit.main()
@UnsupportedAppUsage
public static void main(String[] argv) {
...
// zygote 永久循环。
caller = zygoteServer.runSelectLoop(abiList);
}
9.4.14 ZygoteService.runSelectLoop()
/**
* 运行 zygote 进程的选择循环。 在新连接发生时接受新连接,并从连接中读取一次一个 spawn-request 值的命令。
* @param abiList 此 zygote 支持的 ABI 列表。
*/
Runnable runSelectLoop(String abiList) {
...
//Session socket accepted from the Zygote server socket
ZygoteConnection connection = peers.get(pollIndex);
//通过 fork 启动 子进程(应用程序)
final Runnable command = connection.processOneCommand(this);
...
}
9.4.15 ZygoteConnection.processOneCommand()
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
Runnable processOneCommand(ZygoteServer zygoteServer) {
...
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);
...
}
fork 出一个新的进程(APP),一个APP的程序入口就是ActivityThread.main()。
9.4.15 ActivityThread.main()
frameworks/base/core/java/android/app/ActivityThread.java
在 ActivityThread 初始化的时候,就已经创建消息循环了,所以在主线程里面创建 Handler 不需要指定 Looper,而如果在其他线程使用Handler,则需要 单独使用Looper.prepare()和Looper.loop() 创建消息循环。
public static void main(String[] args) {
...
//初始化当前进程的 Looper 对象
Looper.prepareMainLooper();
...
ActivityThread thread = new ActivityThread();
//此处创建Application
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// 调用 Looper 的 loop 方法开启无限循环。
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
Looper :从 MessageQueue 中取出 Message,然后处理 Message 中指定的任务(startActivity)。
至此,不管是调用 startActivity() 启动页面,还是调用 startActivity() 开启其他进程的界面都算完成了。
如有问题麻烦指正。
相关推荐
❤️ Android 应用是如何启动的?❤️
❤️Android Runtime (ART) 和 Dalvik❤️
❤️Android Apk 的打包过程 ❤️ 只需两幅图
❤️Android 从源码解读 Apk 的安装过程 ❤️
标签:...,java,String,startActivity,int,boolean,源码,Activity,Android 来源: https://blog.csdn.net/g984160547/article/details/120676574