赞
踩
Activity 的启动流程
这里我们以API 28 版本为例。源码太长,文中的代码片段都为截取重要部分。
首先我们从Activity 的startActivity()开始,
- //Activity.java
-
- public void startActivity(Intent intent) {
-
- this.startActivity(intent, null);
-
- }
这里调用了一个重载方法,statActivity(Intent intent,Bundle options)
- @Override
-
- public void startActivity(Intent intent, @Nullable Bundle options) {
-
- ......
-
- startActivityForResult(intent, -1);
-
- ......
-
- }
接着我们来到了startActivityForResult() 方法
- public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
-
- @Nullable Bundle options) {
-
- ......
-
- Instrumentation.ActivityResult ar =
-
- mInstrumentation.execStartActivity(
-
- this, mMainThread.getApplicationThread(), mToken, this,
-
- intent, requestCode, options);
-
- ......
-
- }
可以看到最终走到了Instrumentation 的execStartActivity() 方法里。
- //Instrumentation.java
-
- public ActivityResult execStartActivity(
- Context who, IBinder contextThread, IBinder token, Activity target,
- Intent intent, int requestCode, Bundle options) {
- IApplicationThread whoThread = (IApplicationThread) contextThread;
-
- ......
- int result = ActivityManager.getService()
- .startActivity(whoThread, who.getBasePackageName(), intent,
- intent.resolveTypeIfNeeded(who.getContentResolver()),
- token, target != null ? target.mEmbeddedID : null,
- requestCode, 0, null, options);
- ......
- }
这里有个参数我们需要注意一下,IBinder contexThread, 可以看到这里是个IBinder对象是用来进程间通信的,可以看到传入的参数是mMainThread.getApplicationThread(),
mMainThread 是AcitivityThread的实例,AcitivityThread维护着main()方法,是应用程序的入口,它管理着应用程序的主线程,内部封装着Acitivity、BroadcastRecevier、Service的启动、切换等操作,但是它不是独立完成这份工作的,以上行为的调度都需要通过系统服务ActivityManagerService来进行。
MainThread的内部类ApplicationThread继承了IApplicationThread.Stub,可以用来进程间通信,实际上应用程序同系统服务ActivityManagerService 的交互正是通过ApplicationThread来进行的,我们应用页面的启动、广播的发送、服务的启动都要通过ApplicationThread 和ActivityMamangerService的通信来进行。
介绍下Instrumentation, Instrumentation 译名为仪表盘,它早于应用Application 初始化,所以可以用来监控系统同应用的交互。我们来看它的类结构
发现它的大部分方法都和应用Application 的创建和生命周期回调、Activity 创建以及生命周期回调有关,后面我们也会看到它在Activity 启动流程中的作用。
我们继续往下走,这里代码来到了ActivityManager.getService().startActivity(),
- //ActivityManager.java
-
- public static IActivityManager getService() {
-
- return IActivityManagerSingleton.get();
-
- }
-
-
- private static final Singleton<IActivityManager> IActivityManagerSingleton =
-
- new Singleton<IActivityManager>() {
-
- @Override
-
- protected IActivityManager create() {
-
- final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
-
- final IActivityManager am = IActivityManager.Stub.asInterface(b);
-
- return am;
-
- }
-
- };
ActivityManager.getService() 这里获取的是一个IActivityManager的单例对象,从单例对象创建的方法中我们可以看到获取了ActivityService系统服务IBinder对象,然后将其转为了IActivityManager, 那么获取的这个系统服务对象到底是谁呢?
其实这个系统服务对象就是我们上文提到的ActivityManagerService(AMS)
- public class ActivityManagerService extends IActivityManager.Stub
-
- implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {}
ActivityManagerService 系统服务是android 系统最重要的服务之一,负责着四大组件的启动、切换、调度以及应用程序的管理和调度,可以说没有它,我们应用的正常运行就无从谈起,回归正题,代码调用来到了ActivityManagerService 的startActivity() 方法,
从这里我们就从我们的应用程序进程通过IPC 通信来到了ActivityManagerSerice所在的进程,
- //ActivityManagerService.java
-
- public final int startActivity(IApplicationThread caller, String callingPackage,
- Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
- int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
-
- return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
-
- resultWho, requestCode, startFlags, profilerInfo, bOptions,
-
- UserHandle.getCallingUserId());
-
- }
这里调用了startActivityAsUser()方法,然后又调用了一个重载方法来到了
- //ActivityManagerService.java
-
- public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
- Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
- int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
- boolean validateIncomingUser) {
-
- ......
-
- return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
-
- .setCaller(caller)
-
- .setCallingPackage(callingPackage)
-
- .setResolvedType(resolvedType)
-
- .setResultTo(resultTo)
-
- .setResultWho(resultWho)
-
- .setRequestCode(requestCode)
-
- .setStartFlags(startFlags)
-
- .setProfilerInfo(profilerInfo)
-
- .setActivityOptions(bOptions)
-
- .setMayWait(userId)
-
- .execute();
-
-
-
- }
可以看到通过mActivityStartController 对象获取了一个ActivityStarter 对象,ActivityStartController 是个用来代理Activity 启动的控制器,ActivtyStarter 也是一个控制器用来解释一个Activity 要如何被启动, 我们看下execute()方法
- //ActivityStarter.java
-
- int execute() {
-
- try {
-
- // TODO(b/64750076): Look into passing request directly to these methods to allow
-
- // for transactional diffs and preprocessing.
-
- if (mRequest.mayWait) {
-
- return startActivityMayWait(mRequest.caller, mRequest.callingUid,
-
- mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
-
- mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
-
- mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
-
- mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
-
- mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
-
- mRequest.inTask, mRequest.reason,
-
- mRequest.allowPendingRemoteAnimationRegistryLookup);
-
- } else {
-
- return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
-
- mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
-
- mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
-
- mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
-
- mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
-
- mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
-
- mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
-
- mRequest.outActivity, mRequest.inTask, mRequest.reason,
-
- mRequest.allowPendingRemoteAnimationRegistryLookup);
-
- }
-
- } finally {
-
- onExecutionComplete();
-
- }
-
- }
可以看到有个判断,如果mRequest.mayWait为true, 则执行startActivityMayWait(),否则执行startActivity(), 这里我们只需要关注startActivityMayWait(), 因为在我们获取ActivityStarter 对象时调用了setMayWait()方法,mayWait 字段则被设为了true.
- //ActivityStarter.java
-
- private int startActivityMayWait(IApplicationThread caller, int callingUid,
- String callingPackage, Intent intent, String resolvedType,
- IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
- IBinder resultTo, String resultWho, int requestCode, int startFlags,
- ProfilerInfo profilerInfo, WaitResult outResult,
- Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
- int userId, TaskRecord inTask, String reason,
- boolean allowPendingRemoteAnimationRegistryLookup) {
-
- // Refuse possible leaked file descriptors
-
- ......
-
- final ActivityRecord[] outRecord = new ActivityRecord[1];
-
- int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
-
- voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
-
- callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
-
- ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
-
- allowPendingRemoteAnimationRegistryLookup);
-
- ......
-
- return res;
-
- }
-
- }
接着调用了startActivity()重载方法,创建了目标活动Activity 的ActivitRcord对象,
- //ActivityStarter.java
-
- private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
- String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
- IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
- IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
- String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
- SafeActivityOptions options,
- boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
- TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) {
-
- ......
-
- ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
-
- callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
-
- resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
-
- mSupervisor, checkedOptions, sourceRecord);
-
-
-
- return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
-
- true /* doResume */, checkedOptions, inTask, outActivity);
-
- }
最终来到了startActivityUnChekced()方法,
- //AcitivityStarter.java
-
- private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
- IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
- int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
- ActivityRecord[] outActivity) {
-
- ......
-
- computeLaunchingTaskFlags();
-
- computeSourceStack();
-
- if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
-
- && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
-
- newTask = true;
-
- result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);
-
- } else if (mSourceRecord != null) {
-
- result = setTaskFromSourceRecord();
-
- } else if (mInTask != null) {
-
- result = setTaskFromInTask();
-
- } else {
-
- setTaskToCurrentTopOrCreateNewTask();
-
- }
-
- mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
-
- mOptions);
-
- ......
-
- mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
-
- mOptions);
-
- return START_SUCCESS;
-
- }
这里我们要理解几个相关类,ActivityStackSupervisor,ActivityStack,TaskRecord,ActivityRecord。
我们从小往大的开始说,ActivityRecord : 当我们启动Actitivity 或者关闭Activity 时,我们经常说这个活动入栈或者出栈了,那到底是什么入栈出栈了呢?就是ActivityRecord对象,Android 系统中用ActivityReocrd来表示Activity, 每一个正在运行的Activity 都对应着一个ActivityReocrd 对象,它存储着Activity 的状态信息包括标识符、所属任务栈、进程信息、启动模式、可见性等。
TaskRecord 任务栈,他是用来表示任务的类,主要用于存储和管理任务的状态信息,帮助系统进行任务的管理和调度,他有几个属性我们可以关注下,affinity 就是我们在清单文件里指定的taskAffinity, ArrayList<ActitivityRecord> mActivities 就是运行在当前任务的所有活动集合,mStack 指的是当前任务所在的活动堆栈。在任务中的Activity是按照入栈出栈的方式管理的。
ActivityStack 活动堆栈, 顾名思义,他是真正用来管理活动入栈出栈的类,他是TaskRecord 和ActivityRecord 的统一上司,管理着一个或多个任务栈,也负责着活动的创建、启动、移除、切换的等调度,ActivityStack 维护着TaskRecord列表同时也记录着当前同用户交互的活动和正在暂停的活动ActivityRecord。
ActivityStackSupervisor, 活动堆栈的管理者,他维护着设备中存在的活动堆栈的信息,譬如 mHomeStack 桌面应用的活动堆栈、mFocusedStack 当前同用户交互的活动堆栈等。
在没有开启多任务的应用程序中,他们的对应关系大致如下:
接着说回startActivityUnChekced() 方法,
这个方法主要做了几件事:
1. computeLaunchingTaskFlag(), 主要是为了计算启动活动的启动标记位launchFlags,不同的标记位决定了目标ActivitRecord最终会放在哪一个TaskRecord中,这里分几种步骤:
2.创建新的TaskRecord 或者复用来源Activity 指定的TaskRecord:
3. 调用目标ActivityReocrd 所在的ActivityStack 中方法 startActivityLocked(),这里主要是通过调用insertTaskAtTop()方法将目标ActivityReocrd 所在TaskRecord 移动到栈顶。
- //AcitivityStack.java
-
- void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,
-
- boolean newTask, boolean keepCurTransition, ActivityOptions options) {
- ......
-
- insertTaskAtTop(rTask, r);
-
- ......
-
- }
-
- }
4. 调用ActivityStackSupervisor 的 resumeFocusedStackTopActivityLocked() 方法
- //AcitivityStackSupervisor.java
-
- boolean resumeFocusedStackTopActivityLocked(
- ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
- ......
- mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
-
- ......
-
- return false;
-
- }
上面我们来到了ActivityStack 的 resumeTopActivityUncheckedLocked() 方法,里面调用了resumeTopActivityInnerLocked()方法,
- //AcitivityStack.java
-
- private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
-
- ......
-
- if (mResumedActivity != null) {
-
- if (DEBUG_STATES) Slog.d(TAG_STATES,
-
- "resumeTopActivityLocked: Pausing " + mResumedActivity);
-
- pausing |= startPausingLocked(userLeaving, false, next, false);
-
- }
-
- mStackSupervisor.startSpecificActivityLocked(next, true, true);
-
- return true;
-
- }
这里有一点要注意的是这里我们调用了一个startPausingLocked ()方法, 如果当前获取焦点的Activity不为null, 我们还要暂停它,最终调用了当前活动的onPause() 方法,也就是说在开启新的Activity之前要先暂停当前Activity,所以为了使新启动的Activity 更快的启动,我们不要在onPause() 方法中做过多的操作。
最终我们又回到了ActivityStackSupervisor中,我们看下startSpecificActivityLocked( )方法
- //AcitivityStackSupervisor.java
-
- void startSpecificActivityLocked(ActivityRecord r,
-
- boolean andResume, boolean checkConfig) {
-
- // Is this activity's application already running?
-
- ProcessRecord app = mService.getProcessRecordLocked(r.processName,
-
- r.info.applicationInfo.uid, true);
-
- if (app != null && app.thread != null) {
-
- try {
-
- if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
-
- || !"android".equals(r.info.packageName)) {
-
- ......
- realStartActivityLocked(r, app, andResume, checkConfig);
-
- return;
-
- } catch (RemoteException e) {
-
- Slog.w(TAG, "Exception when starting activity "
-
- + r.intent.getComponent().flattenToShortString(), e);
-
- }
-
- }
-
- mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
-
- "activity", r.intent.getComponent(), false, false, true);
-
- }
这个 方法中判断了我们目标ActivityReocrd 所在进程是否存在,如果不存在,则需要ActivityManagerService创建进程,如果存在则调用 realStartActivityLocked(), 这里我们先假设应用进程已经存在,然后我们看下realStartActivityLocked() 方法。
- //AcitivityStackSupervisor.java
-
- final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
-
- boolean andResume, boolean checkConfig) throws RemoteException {
-
- ......
-
- // Create activity launch transaction.
-
- final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread, r.appToken);
-
- clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),...));
-
-
- mService.getLifecycleManager().scheduleTransaction(clientTransaction);
-
-
-
- ......
-
-
-
- return true;
-
- }
这里我们创建了一个事务,可以看到创建事务的时候需要将目标应用的ApplicationThread 作为参数
- //ClientTransaction.java
- 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;
-
- }
并且给了事务一个LaunchActivtyItem 的回调callBack,然后调用AMS 中的ClientLifecycleManager 执行了该事务。
- //ClientLifecyleManager.java
- void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
-
- final IApplicationThread client = transaction.getClient();
-
- transaction.schedule();
-
- ……
-
- }
这里调用了事务的schedule()方法,
- //ClientTransaction.java
- public void schedule() throws RemoteException {
-
- mClient.scheduleTransaction(this);
-
- }
这里的mClient 是我们创建事务的时候传入的app.thread,它是目标进程的ApplicationThread对象, 这时候我们终于从ActivityManagerService 来到了目标进程的ApplicationThread。
- //ApplicationThread.java
-
- public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
-
- ActivityThread.this.scheduleTransaction(transaction);
- }
ApplicationThread 是ActivityThread 的内部类,它直接调用了ActivityThread 的scheduleTransaction() 方法, 有没有在ActivityThread 找这个方法没有找到的童鞋呢,其实这个方法是定义在抽象类ClientTransactionHandler 中的,ActivityThread 继承了这个类,我们看下这个方法
- //ActivityThread.java
-
- void scheduleTransaction(ClientTransaction transaction) {
-
- transaction.preExecute(this);
-
- sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
- }
来到了ActivityThread 的sendMessage() 方法,通过ActivityThread 维护的Handler mH 发送了 标记 为ActivityThread.H.EXECUTE_TRANSACTION 的消息,接着我们来到Handler 的handleMessage方法中,
-
- void handleMessage(Message msg){
-
- case EXECUTE_TRANSACTION:
-
- final ClientTransaction transaction = (ClientTransaction) msg.obj;
-
- mTransactionExecutor.execute(transaction)
-
- break;
-
-
- }
可以看到这里用TransactionExecutor 对象调用了execute 执行了启动Activity的事务,TransactionExecutor 是ActivityThread 的一个属性,TransactionExecutor mTransactionExecutor = new TransactionExecutor(this), 可以看到它的构造函数中需要ClientTransactionHandler 作为参数,而ActivityThread 正好继承了ClientTransactionHandler. 接着往下走,
- // TransactionExecutor.java
-
- public void execute(ClientTransaction transaction) {
- ……
-
- executeCallbacks(transaction);
-
- }
- public void executeCallbacks(ClientTransaction transaction) {
-
- final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
-
- if (callbacks == null) {
-
- // No callbacks to execute, return early.
-
- return;
-
- }
-
- final int size = callbacks.size();
-
- for (int i = 0; i < size; ++i) {
-
- final ClientTransactionItem item = callbacks.get(i);
-
- ......
-
- item.execute(mTransactionHandler, token, mPendingActions);
-
- item.postExecute(mTransactionHandler, token, mPendingActions);
-
- ......
-
- }
-
- }
还记得我们创建事务的时候传入的callBack LaunchActivityItem 吗? 这里饶了一大圈就是调用了它的execute() 方法
- //LaunchActivityItem.java
-
- public void execute(ClientTransactionHandler client, IBinder token,
- PendingTransactionActions pendingActions) {
-
- ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
-
- mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
-
- mPendingResults, mPendingNewIntents, mIsForward,
-
- mProfilerInfo, client);
-
- client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
- }
可以看到这里调用了ClientTransactionHandler 的handleLaunchActivity() 方法,我们上文提到过ActivityThead 继承了ClicentTransactionHandler,所以这里来到了ActivityThread 的handleLaunchActivity() 方法
- //ActivityThread.java
-
- public Activity handleLaunchActivity(ActivityClientRecord r,
- PendingTransactionActions pendingActions, Intent customIntent) {
- ......
-
- final Activity a = performLaunchActivity(r, customIntent);
-
- ......
-
- return a;
- }
这里来到了performLauncherActivity()方法
- //ActivityThread.java
- private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
- //创建上下文
-
- ContextImpl appContext = createBaseContextForActivity(r);
-
- Activity activity = null;
-
- java.lang.ClassLoader cl = appContext.getClassLoader();
-
- //创建Activity
- activity = mInstrumentation.newActivity(
-
- cl, component.getClassName(), r.intent);
-
-
- try {
-
- Application app = r.packageInfo.makeApplication(false, mInstrumentation);
-
- //绑定上下文,创建PhoneWindow
-
- 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);
- //调用Activity onCreate()
-
- mInstrumentation.callActivityOnCreate(activity, r.state);
-
- r.activity = activity;
-
- }
-
- ......
-
- return activity;
-
- }
这个方法中给目标Activity创建上下文Context, 通过Instrumentation.newActivity()创建目标Activity实例, 通过目标Activity attach() 方法和上下文绑定并且创建PhoneWindow,通过Instumentation.callActivityOnCreate() 调用目标Activity 的生命周期onCreate()方法,至此 一个Activity 的算是被启动了。
整理的启动流程图如下,以作参考
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。