Activity的启动过程详解(基于10.0源码)
Editor's Note
The following article is from 胡飞洋 Author 胡飞洋
这是JsonChao的第 87 期分享
Activity概述
话说Android中有四大组件:Activity、Service、BroadcastReceiver、ContentProvider。我们最常接触也是用户直接感受到的就是Activity了,今天来就说说Android启动的执行过程和工作原理。
Activity是一种 展示型组件,用于展示给用户一个可以交互的页面。Activity是Android中最重要的组件,对用户来说,所有的Activity就是一个App的全部,而其他组件用户是不能直接感知的。在开发层面,要启动一个Activity可以使用Intent,分显式和隐式,并且还可以设置Activity的启动模式。
Android系统对四大组件都做了很大程度的封装,这样我们可以快速使用组件。Activity的启动在系统封装后,变的极为简单,显示启动activity代码如下:
1Intent intent = new Intent(this, TestActivity.class);
2this.startActivity(intent);
这样就可以启动TestActivity了,那么问题来了,
这个代码是如何启动一个Activity的?
里面做了哪些事情?
onCreate这些生命周期是何时执行的?
Activity对象何时创建的?
视图是怎么处理以及何时可见的?
那么为啥需要了解这些问题呢?不了解 ,平时开发好像也没啥问题啊。其实不然,解决这些问题后,你会对Android系统有更深层次的理解,也会学习到系统源码优秀的设计。并且对解决一些高级问题和深入的性能优化问题有很大帮助,是技术进阶的必要阶段。这就需要我们通过阅读源码来梳理这些问题,但另一方面,系统源码是很庞大繁杂的,我们需要带着问题抓住主流程,不能陷入代码细节——这是阅读系统源码以及其他第三方库源码的正确姿势。
流程分析
Activity启动的发起
下面我们就来对Activity的工作流程进行梳理,达到对Activity整体流程的掌握。从startActivity方法开始,会走到startActivityForResult方法:
1 public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
2 @Nullable Bundle options) {
3 if (mParent == null) {
4 options = transferSpringboardActivityOptions(options);
5 Instrumentation.ActivityResult ar =
6 mInstrumentation.execStartActivity(
7 this, mMainThread.getApplicationThread(), mToken, this,
8 intent, requestCode, options);
9 if (ar != null) {
10 mMainThread.sendActivityResult(
11 mToken, mEmbeddedID, requestCode, ar.getResultCode(),
12 ar.getResultData());
13 }
14 if (requestCode >= 0) {
15 mStartedActivity = true;
16 }
17
18 cancelInputsAndStartExitTransition(options);
19 } else {
20 ...
21 }
22 }
看到里面调用了mInstrumentation.execStartActivity方法,其中一个参数mMainThread.getApplicationThread(),它的类型是ApplicationThread,ApplicationThread是ActivityThread的内部类,继承IApplicationThread.Stub,也是个Binder对象,在Activity工作流程中有重要作用。而Instrumentation具有跟踪application及activity生命周期的功能,用于android 应用测试框架中代码检测。接着看下mInstrumentation.execStartActivity方法:
1 public ActivityResult execStartActivity(
2 Context who, IBinder contextThread, IBinder token, Activity target,
3 Intent intent, int requestCode, Bundle options) {
4 IApplicationThread whoThread = (IApplicationThread) contextThread;
5 Uri referrer = target != null ? target.onProvideReferrer() : null;
6 if (referrer != null) {
7 intent.putExtra(Intent.EXTRA_REFERRER, referrer);
8 }
9 ...
10
11 try {
12 intent.migrateExtraStreamToClipData();
13 intent.prepareToLeaveProcess(who);
14 int result = ActivityManager.getService()
15 .startActivity(whoThread, who.getBasePackageName(), intent,
16 intent.resolveTypeIfNeeded(who.getContentResolver()),
17 token, target != null ? target.mEmbeddedID : null,
18 requestCode, 0, null, options);
19 checkStartActivityResult(result, intent);
20 } catch (RemoteException e) {
21 throw new RuntimeException("Failure from system", e);
22 }
23 return null;
24 }
这里看到Activity的启动又交给了ActivityManager.getService(),这是啥?跟进去看看:
1 public static IActivityManager getService() {
2 return IActivityManagerSingleton.get();
3 }
4 private static final Singleton<IActivityManager> IActivityManagerSingleton =
5 new Singleton<IActivityManager>() {
6 @Override
7 protected IActivityManager create() {
8 final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
9 final IActivityManager am = IActivityManager.Stub.asInterface(b);
10 return am;
11 }
12 };
看到这里你应该明白了:这里是获取一个跨进程的服务。然后我们看下著名的ActivityManagerService类
1public class ActivityManagerService extends IActivityManager.Stub
2 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback
3
ActivityManagerService继承IActivityManager.Stub,实际也就是继承了Binder并且实现了IActivityManager这个Binder接口,AMS也就是一个Binder,是IActivityManager的集体实现。所以ActivityManager.getService()获取的Binder对象,具体实现是ActivityManagerService(AMS),并且是通过单例提供服务的。
然后ActivityManager.getService().startActivity有个返回值result,且调用了checkStartActivityResult(result, intent):
1 public static void checkStartActivityResult(int res, Object intent) {
2 if (!ActivityManager.isStartResultFatalError(res)) {
3 return;
4 }
5
6 switch (res) {
7 case ActivityManager.START_INTENT_NOT_RESOLVED:
8 case ActivityManager.START_CLASS_NOT_FOUND:
9 if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
10 throw new ActivityNotFoundException(
11 "Unable to find explicit activity class "
12 + ((Intent)intent).getComponent().toShortString()
13 + "; have you declared this activity in your AndroidManifest.xml?");
14 throw new ActivityNotFoundException(
15 "No Activity found to handle " + intent);
16 case ActivityManager.START_PERMISSION_DENIED:
17 throw new SecurityException("Not allowed to start activity "
18 + intent);
19 ...
20
21 case ActivityManager.START_CANCELED:
22 throw new AndroidRuntimeException("Activity could not be started for "
23 + intent);
24 default:
25 throw new AndroidRuntimeException("Unknown error code "
26 + res + " when starting " + intent);
27 }
28 }
这是用来检查Activity启动的结果,如果发生致命错误,就会抛出对应的异常。看到第一个case中就抛出了 have you declared this activity in your AndroidManifest.xml?——如果Activity没在Manifest中注册就会有这个错误。
Activity的管理——AMS
好了,到这里,Activity的启动就转移到系统进程提供的服务AMS中了,接着看AMS的startActivity:
1 @Override
2 public int startActivity(IApplicationThread caller, String callingPackage,
3 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
5 return mActivityTaskManager.startActivity(caller, callingPackage, intent, resolvedType,
6 resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions);
7 }
AMS把启动转移到了ActivityTaskManagerService(ATMS)中了,ATMS用于管理Activity及其容器(任务、堆栈、显示等)的系统服务。接着看:
1//ActivityTaskManagerService
2 @Override
3 public final int startActivity(IApplicationThread caller, String callingPackage,
4 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
5 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
6 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
7 resultWho, requestCode, startFlags, profilerInfo, bOptions,
8 UserHandle.getCallingUserId());
9 }
10
11 @Override
12 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
13 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
14 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
15 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
16 resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
17 true /*validateIncomingUser*/);
18 }
19
20 int startActivityAsUser(IApplicationThread caller, String callingPackage,
21 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
22 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
23 boolean validateIncomingUser) {
24 enforceNotIsolatedCaller("startActivityAsUser");
25
26 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
27 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
28
29 // TODO: Switch to user app stacks here.
30 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
31 .setCaller(caller)
32 .setCallingPackage(callingPackage)
33 .setResolvedType(resolvedType)
34 .setResultTo(resultTo)
35 .setResultWho(resultWho)
36 .setRequestCode(requestCode)
37 .setStartFlags(startFlags)
38 .setProfilerInfo(profilerInfo)
39 .setActivityOptions(bOptions)
40 .setMayWait(userId)
41 .execute();
42
43 }
跟到startActivityAsUser中,通过getActivityStartController().obtainStarter方法获取ActivityStarter实例 然后调用一系列方法,最后的execute()方法是开始启动activity:
1 int execute() {
2 try {
3 // TODO(b/64750076): Look into passing request directly to these methods to allow
4 // for transactional diffs and preprocessing.
5 if (mRequest.mayWait) {
6 return startActivityMayWait(mRequest.caller, mRequest.callingUid,
7 mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
8 mRequest.intent, mRequest.resolvedType,
9 mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
10 mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
11 mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
12 mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
13 mRequest.inTask, mRequest.reason,
14 mRequest.allowPendingRemoteAnimationRegistryLookup,
15 mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
16 } else {
17 return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
18 mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
19 mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
20 mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
21 mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
22 mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
23 mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
24 mRequest.outActivity, mRequest.inTask, mRequest.reason,
25 mRequest.allowPendingRemoteAnimationRegistryLookup,
26 mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
27 }
28 } finally {
29 onExecutionComplete();
30 }
31 }
分了两种情况,不过 不论startActivityMayWait还是startActivity最终都是走到下面这个startActivity方法:
1 private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
2 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
3 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
4 ActivityRecord[] outActivity, boolean restrictedBgActivity) {
5 int result = START_CANCELED;
6 final ActivityStack startedActivityStack;
7 try {
8 mService.mWindowManager.deferSurfaceLayout();
9 result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
10 startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
11 } finally {
12 final ActivityStack currentStack = r.getActivityStack();
13 startedActivityStack = currentStack != null ? currentStack : mTargetStack;
14
15 ...
16 }
17
18 postStartActivityProcessing(r, result, startedActivityStack);
19 return result;
20 }
里面有调用了startActivityUnchecked方法,startActivityUnchecked内部调用了ActivityStack的startActivityLocked方法,startActivityLocked内部调用ensureActivitiesVisibleLocked方法,ensureActivitiesVisibleLocked又调用makeVisibleAndRestartIfNeeded方法,来看下:
1 private boolean makeVisibleAndRestartIfNeeded(ActivityRecord starting, int configChanges,
2 boolean isTop, boolean andResume, ActivityRecord r) {
3 // We need to make sure the app is running if it's the top, or it is just made visible from
4 // invisible. If the app is already visible, it must have died while it was visible. In this
5 // case, we'll show the dead window but will not restart the app. Otherwise we could end up
6 // thrashing.
7 if (isTop || !r.visible) {
8 // This activity needs to be visible, but isn't even running...
9 // get it started and resume if no other stack in this stack is resumed.
10 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Start and freeze screen for " + r);
11 if (r != starting) {
12 r.startFreezingScreenLocked(r.app, configChanges);
13 }
14 if (!r.visible || r.mLaunchTaskBehind) {
15 if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Starting and making visible: " + r);
16 r.setVisible(true);
17 }
18 if (r != starting) {
19 // We should not resume activities that being launched behind because these
20 // activities are actually behind other fullscreen activities, but still required
21 // to be visible (such as performing Recents animation).
22 mStackSupervisor.startSpecificActivityLocked(r, andResume && !r.mLaunchTaskBehind,
23 true /* checkConfig */);
24 return true;
25 }
26 }
27 return false;
28 }
看到最后调用了ActivityStackSupervisor的startSpecificActivityLocked方法:
1 void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
2 // Is this activity's application already running?
3 final WindowProcessController wpc =
4 mService.getProcessController(r.processName, r.info.applicationInfo.uid);
5
6 boolean knownToBeDead = false;
7 if (wpc != null && wpc.hasThread()) {
8 try {
9 realStartActivityLocked(r, wpc, andResume, checkConfig);
10 return;
11 } catch (RemoteException e) {
12 Slog.w(TAG, "Exception when starting activity "
13 + r.intent.getComponent().flattenToShortString(), e);
14 }
15
16 // If a dead object exception was thrown -- fall through to
17 // restart the application.
18 knownToBeDead = true;
19 }
20
21 ...
22 }
接着调用了realStartActivityLocked方法:
1 boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
2 boolean andResume, boolean checkConfig) throws RemoteException {
3
4 ...
5
6 // Create activity launch transaction.
7 final ClientTransaction clientTransaction = ClientTransaction.obtain(
8 proc.getThread(), r.appToken);
9
10 final DisplayContent dc = r.getDisplay().mDisplayContent;
11 clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
12 System.identityHashCode(r), r.info,
13 // TODO: Have this take the merged configuration instead of separate global
14 // and override configs.
15 mergedConfiguration.getGlobalConfiguration(),
16 mergedConfiguration.getOverrideConfiguration(), r.compat,
17 r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
18 r.icicle, r.persistentState, results, newIntents,
19 dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
20 r.assistToken));
21
22 // Set desired final state.
23 final ActivityLifecycleItem lifecycleItem;
24 if (andResume) {
25 lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
26 } else {
27 lifecycleItem = PauseActivityItem.obtain();
28 }
29 clientTransaction.setLifecycleStateRequest(lifecycleItem);
30
31 // Schedule transaction.
32 mService.getLifecycleManager().scheduleTransaction(clientTransaction);
33
34 ...
35
36 return true;
37 }
中间有段代码如上,通过 ClientTransaction.obtain( proc.getThread(), r.appToken)获取了clientTransaction,其中参数proc.getThread()是IApplicationThread,就是前面提到的ApplicationThread在系统进程的代理。
ClientTransaction是包含一系列的message的容器,message用于 发送到客户端,包含回调方法和生命周期状态。
接着看,使用clientTransaction.addCallback添加了LaunchActivityItem实例:
1 //都是用来发送到客户端的
2 private List<ClientTransactionItem> mActivityCallbacks;
3
4 public void addCallback(ClientTransactionItem activityCallback) {
5 if (mActivityCallbacks == null) {
6 mActivityCallbacks = new ArrayList<>();
7 }
8 mActivityCallbacks.add(activityCallback);
9 }
看下LaunchActivityItem实例的获取:
1 /** Obtain an instance initialized with provided params. */
2 public static LaunchActivityItem obtain(Intent intent, int ident, ActivityInfo info,
3 Configuration curConfig, Configuration overrideConfig, CompatibilityInfo compatInfo,
4 String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
5 PersistableBundle persistentState, List<ResultInfo> pendingResults,
6 List<ReferrerIntent> pendingNewIntents, boolean isForward, ProfilerInfo profilerInfo,
7 IBinder assistToken) {
8 LaunchActivityItem instance = ObjectPool.obtain(LaunchActivityItem.class);
9 if (instance == null) {
10 instance = new LaunchActivityItem();
11 }
12 setValues(instance, intent, ident, info, curConfig, overrideConfig, compatInfo, referrer,
13 voiceInteractor, procState, state, persistentState, pendingResults,
14 pendingNewIntents, isForward, profilerInfo, assistToken);
15
16 return instance;
17 }
new了一个LaunchActivityItem然后设置各种值。我们从名字就能看出,它就是用来启动activity的。它是怎么发挥作用的呢?接着看:
回到realStartActivityLocked方法,接着调用了mService.getLifecycleManager().scheduleTransaction(clientTransaction),mService是前面提到了ActivityTaskManagerService,getLifecycleManager()方法获取的是ClientLifecycleManager实例,它的scheduleTransaction方法如下:
1 void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
2 final IApplicationThread client = transaction.getClient();
3 transaction.schedule();
4 if (!(client instanceof Binder)) {
5 transaction.recycle();
6 }
7 }
就是调用ClientTransaction的schedule方法,那就看看:
1 public void schedule() throws RemoteException {
2 mClient.scheduleTransaction(this);
3 }
很简单,就是调用IApplicationThread的scheduleTransaction方法。由于IApplicationThread是ApplicationThread在系统进程的代理,所以真正执行的地方就是 客户端的ApplicationThread中了。也就是说,Activity启动的操作又跨进程的还给了客户端。
好了,到这里我们稍稍梳理下:启动Activity的操作从客户端 跨进程 转移到 AMS,AMS通过ActivityTaskManagerService、ActivityStarter、ActivityStack、ActivityStackSupervisor 对 Activity任务、activity栈、Activity记录 管理后,又用过跨进程把正在启动过程又转移到了客户端。
线程切换及消息处理——mH
接着上面的分析,我们找到ApplicationThread的scheduleTransaction方法:
1 @Override
2 public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
3 ActivityThread.this.scheduleTransaction(transaction);
4 }
那就再看ActivityThread的scheduleTransaction方法,实际在其父类ClientTransactionHandler中:
1 void scheduleTransaction(ClientTransaction transaction) {
2 transaction.preExecute(this);
3 sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
4 }
使用sendMessage发送消息,参数是ActivityThread.H.EXECUTE_TRANSACTION和transaction,接着看:
1 void sendMessage(int what, Object obj) {
2 sendMessage(what, obj, 0, 0, false);
3 }
4 private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
5 if (DEBUG_MESSAGES) {
6 Slog.v(TAG,
7 "SCHEDULE " + what + " " + mH.codeToString(what) + ": " + arg1 + " / " + obj);
8 }
9 Message msg = Message.obtain();
10 msg.what = what;
11 msg.obj = obj;
12 msg.arg1 = arg1;
13 msg.arg2 = arg2;
14 if (async) {
15 msg.setAsynchronous(true);
16 }
17 mH.sendMessage(msg);
18 }
最后调用了mH.sendMessage(msg),mH是个啥?我们看看:
1//ActivityThread
2final H mH = new H();
3
4 class H extends Handler {
5 public static final int BIND_APPLICATION = 110;
6 @UnsupportedAppUsage
7 public static final int EXIT_APPLICATION = 111;
8 @UnsupportedAppUsage
9 public static final int RECEIVER = 113;
10 @UnsupportedAppUsage
11 public static final int CREATE_SERVICE = 114;
12 @UnsupportedAppUsage
13 public static final int SERVICE_ARGS = 115;
14 @UnsupportedAppUsage
15 public static final int STOP_SERVICE = 116;
16
17 public static final int CONFIGURATION_CHANGED = 118;
18 ...
19 @UnsupportedAppUsage
20 public static final int BIND_SERVICE = 121;
21 @UnsupportedAppUsage
22 public static final int UNBIND_SERVICE = 122;
23 ...
24
25 public static final int EXECUTE_TRANSACTION = 159;
26
27 public static final int RELAUNCH_ACTIVITY = 160;
28 public static final int PURGE_RESOURCES = 161;
29
30 public void handleMessage(Message msg) {
31 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
32 switch (msg.what) {
33 case BIND_APPLICATION:
34 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
35 AppBindData data = (AppBindData)msg.obj;
36 handleBindApplication(data);
37 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
38 break;
39 case EXIT_APPLICATION:
40 if (mInitialApplication != null) {
41 mInitialApplication.onTerminate();
42 }
43 Looper.myLooper().quit();
44 break;
45 case RECEIVER:
46 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
47 handleReceiver((ReceiverData)msg.obj);
48 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
49 break;
50 case CREATE_SERVICE:
51 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
52 handleCreateService((CreateServiceData)msg.obj);
53 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
54 break;
55 case BIND_SERVICE:
56 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
57 handleBindService((BindServiceData)msg.obj);
58 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
59 break;
60 case UNBIND_SERVICE:
61 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
62 handleUnbindService((BindServiceData)msg.obj);
63 schedulePurgeIdler();
64 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
65 break;
66 case SERVICE_ARGS:
67 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj)));
68 handleServiceArgs((ServiceArgsData)msg.obj);
69 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
70 break;
71 case STOP_SERVICE:
72 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
73 handleStopService((IBinder)msg.obj);
74 schedulePurgeIdler();
75 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
76 break;
77 case CONFIGURATION_CHANGED:
78 handleConfigurationChanged((Configuration) msg.obj);
79 break;
80
81 ...
82
83 case EXECUTE_TRANSACTION:
84 final ClientTransaction transaction = (ClientTransaction) msg.obj;
85 mTransactionExecutor.execute(transaction);
86 if (isSystem()) {
87 // Client transactions inside system process are recycled on the client side
88 // instead of ClientLifecycleManager to avoid being cleared before this
89 // message is handled.
90 transaction.recycle();
91 }
92 // TODO(lifecycler): Recycle locally scheduled transactions.
93 break;
94 case RELAUNCH_ACTIVITY:
95 handleRelaunchActivityLocally((IBinder) msg.obj);
96 break;
97 case PURGE_RESOURCES:
98 schedulePurgeIdler();
99 break;
100 }
101 Object obj = msg.obj;
102 if (obj instanceof SomeArgs) {
103 ((SomeArgs) obj).recycle();
104 }
105 if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
106 }
107 }
mH是在创建ActivityThread实例时赋值的,是自定义Handler子类H的实例,也就是在ActivityThread的main方法中,并且初始化是已经主线程已经有了mainLooper,所以,使用这个mH来sendMessage就把消息发送到了主线程。
那么是从哪个线程发送的呢?那就要看看ApplicationThread的scheduleTransaction方法是执行在哪个线程了。根据IPC知识,我们知道,服务器的Binder方法运行在Binder的线程池中,也就是说系统进行跨进程调用ApplicationThread的scheduleTransaction就是执行在Binder的线程池中的了。
到这里,消息就在主线程处理了,那么是怎么处理Activity的启动的呢?接着看。我们找到ActivityThread.H.EXECUTE_TRANSACTION这个消息的处理,就在handleMessage方法的倒数第三个case(就在上面代码):取出ClientTransaction实例,调用TransactionExecutor的execute方法,那就看看:
1 public void execute(ClientTransaction transaction) {
2 if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");
3
4 final IBinder token = transaction.getActivityToken();
5 ...
6 executeCallbacks(transaction);
7
8 executeLifecycleState(transaction);
9 ...
10 }
继续跟进executeCallbacks方法:
1 public void executeCallbacks(ClientTransaction transaction) {
2 final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
3 if (callbacks == null || callbacks.isEmpty()) {
4 // No callbacks to execute, return early.
5 return;
6 }
7 if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callbacks in transaction");
8
9 final IBinder token = transaction.getActivityToken();
10 ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
11
12 // In case when post-execution state of the last callback matches the final state requested
13 // for the activity in this transaction, we won't do the last transition here and do it when
14 // moving to final state instead (because it may contain additional parameters from server).
15 final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();
16 final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState()
17 : UNDEFINED;
18 // Index of the last callback that requests some post-execution state.
19 final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);
20
21 final int size = callbacks.size();
22 for (int i = 0; i < size; ++i) {
23 final ClientTransactionItem item = callbacks.get(i);
24 ...
25 item.execute(mTransactionHandler, token, mPendingActions);
26 item.postExecute(mTransactionHandler, token, mPendingActions);
27 ...
28 }
29 }
遍历callbacks,调用ClientTransactionItem的execute方法,而我们这里要关注的是ClientTransactionItem的子类LaunchActivityItem,看下它的execute方法:
1 public void execute(ClientTransactionHandler client, IBinder token,
2 PendingTransactionActions pendingActions) {
3 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
4 ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
5 mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
6 mPendingResults, mPendingNewIntents, mIsForward,
7 mProfilerInfo, client, mAssistToken);
8 client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
9 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
10 }
里面调用了client.handleLaunchActivity方法,client是ClientTransactionHandler的实例,是在TransactionExecutor构造方法传入的,TransactionExecutor创建是在ActivityThread中:
1//ActivityThread
2private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
所以,client.handleLaunchActivity方法就是ActivityThread的handleLaunchActivity方法。
好了,到这里 ApplicationThread把启动Activity的操作,通过mH切到了主线程,走到了ActivityThread的handleLaunchActivity方法。
Activity启动核心实现——初始化及生命周期
那就接着看:
1 public Activity handleLaunchActivity(ActivityClientRecord r,
2 PendingTransactionActions pendingActions, Intent customIntent) {
3 ...
4 final Activity a = performLaunchActivity(r, customIntent);
5 ...
6 return a;
7 }
继续跟performLaunchActivity方法,这里就是activity 启动的核心实现了:
1 /** activity 启动的核心实现. */
2 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
3 //1、从ActivityClientRecord获取待启动的Activity的组件信息
4 ActivityInfo aInfo = r.activityInfo;
5 if (r.packageInfo == null) {
6 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
7 Context.CONTEXT_INCLUDE_CODE);
8 }
9
10 ComponentName component = r.intent.getComponent();
11 if (component == null) {
12 component = r.intent.resolveActivity(
13 mInitialApplication.getPackageManager());
14 r.intent.setComponent(component);
15 }
16
17 if (r.activityInfo.targetActivity != null) {
18 component = new ComponentName(r.activityInfo.packageName,
19 r.activityInfo.targetActivity);
20 }
21 //创建ContextImpl对象
22 ContextImpl appContext = createBaseContextForActivity(r);
23 Activity activity = null;
24 try {
25 //2、创建activity实例
26 java.lang.ClassLoader cl = appContext.getClassLoader();
27 activity = mInstrumentation.newActivity(
28 cl, component.getClassName(), r.intent);
29 StrictMode.incrementExpectedActivityCount(activity.getClass());
30 r.intent.setExtrasClassLoader(cl);
31 r.intent.prepareToEnterProcess();
32 if (r.state != null) {
33 r.state.setClassLoader(cl);
34 }
35 } catch (Exception e) {
36 ..
37 }
38 try {
39 //3、创建Application对象(如果没有的话)
40 Application app = r.packageInfo.makeApplication(false, mInstrumentation);
41 ...
42 if (activity != null) {
43 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
44 Configuration config = new Configuration(mCompatConfiguration);
45 if (r.overrideConfig != null) {
46 config.updateFrom(r.overrideConfig);
47 }
48
49 Window window = null;
50 if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
51 window = r.mPendingRemoveWindow;
52 r.mPendingRemoveWindow = null;
53 r.mPendingRemoveWindowManager = null;
54 }
55 appContext.setOuterContext(activity);
56
57 //4、attach方法为activity关联上下文环境
58 activity.attach(appContext, this, getInstrumentation(), r.token,
59 r.ident, app, r.intent, r.activityInfo, title, r.parent,
60 r.embeddedID, r.lastNonConfigurationInstances, config,
61 r.referrer, r.voiceInteractor, window, r.configCallback,
62 r.assistToken);
63
64 if (customIntent != null) {
65 activity.mIntent = customIntent;
66 }
67 r.lastNonConfigurationInstances = null;
68 checkAndBlockForNetworkAccess();
69 activity.mStartedActivity = false;
70 int theme = r.activityInfo.getThemeResource();
71 if (theme != 0) {
72 activity.setTheme(theme);
73 }
74
75 activity.mCalled = false;
76
77 //5、调用生命周期onCreate
78 if (r.isPersistable()) {
79 mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
80 } else {
81 mInstrumentation.callActivityOnCreate(activity, r.state);
82 }
83 if (!activity.mCalled) {
84 throw new SuperNotCalledException(
85 "Activity " + r.intent.getComponent().toShortString() +
86 " did not call through to super.onCreate()");
87 }
88 r.activity = activity;
89 }
90 r.setState(ON_CREATE);
91
92 synchronized (mResourcesManager) {
93 mActivities.put(r.token, r);
94 }
95
96 }
97 ...
98
99 return activity;
100 }
performLaunchActivity主要完成以下事情:
从ActivityClientRecord获取待启动的Activity的组件信息
通过mInstrumentation.newActivity方法使用类加载器创建activity实例
通过LoadedApk的makeApplication方法创建Application对象,内部也是通过mInstrumentation使用类加载器,创建后就调用了instrumentation.callApplicationOnCreate方法,也就是Application的onCreate方法。
创建ContextImpl对象并通过activity.attach方法对重要数据初始化,关联了Context的具体实现ContextImpl,attach方法内部还完成了window创建,这样Window接收到外部事件后就能传递给Activity了。
调用Activity的onCreate方法,是通过 mInstrumentation.callActivityOnCreate方法完成。
到这里Activity的onCreate方法执行完,那么onStart、onResume呢?
上面看到LaunchActivityItem,是用来启动Activity的,也就是走到Activity的onCreate,那么是不是有 "XXXActivityItem"呢? 有的:
LaunchActivityItem 远程App端的onCreate生命周期事务
ResumeActivityItem 远程App端的onResume生命周期事务
PauseActivityItem 远程App端的onPause生命周期事务
StopActivityItem 远程App端的onStop生命周期事务
DestroyActivityItem 远程App端onDestroy生命周期事务
另外梳理过程中涉及的几个类:
ClientTransaction 客户端事务控制者
ClientLifecycleManager 客户端的生命周期事务控制者
TransactionExecutor 远程通信事务执行者
那么我们再来看看ResumeActivityItem吧。
我们再来重新看看在ActivityStackSupervisor的realStartActivityLocked方法:
1 boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
2 boolean andResume, boolean checkConfig) throws RemoteException {
3 ...
4 // Create activity launch transaction.
5 final ClientTransaction clientTransaction = ClientTransaction.obtain(
6 proc.getThread(), r.appToken);
7
8 final DisplayContent dc = r.getDisplay().mDisplayContent;
9 clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
10 System.identityHashCode(r), r.info,
11 mergedConfiguration.getGlobalConfiguration(),
12 mergedConfiguration.getOverrideConfiguration(), r.compat,
13 r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
14 r.icicle, r.persistentState, results, newIntents,
15 dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
16 r.assistToken));
17
18 // Set desired final state.
19 final ActivityLifecycleItem lifecycleItem;
20 //这里ResumeActivityItem
21 if (andResume) {
22 lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
23 } else {
24 lifecycleItem = PauseActivityItem.obtain();
25 }
26 clientTransaction.setLifecycleStateRequest(lifecycleItem);
27
28 // Schedule transaction.
29 mService.getLifecycleManager().scheduleTransaction(clientTransaction);
30
31 ...
32
33 return true;
34 }
前面只说了通过clientTransaction.addCallback添加LaunchActivityItem实例,在注意下面接着调用了clientTransaction.setLifecycleStateRequest(lifecycleItem)方法,lifecycleItem是ResumeActivityItem或PauseActivityItem实例,这里我们关注ResumeActivityItem,先看下setLifecycleStateRequest方法:
1 /**
2 * Final lifecycle state in which the client activity should be after the transaction is
3 * executed.
4 */
5 private ActivityLifecycleItem mLifecycleStateRequest;
6
7 public void setLifecycleStateRequest(ActivityLifecycleItem stateRequest) {
8 mLifecycleStateRequest = stateRequest;
9 }
mLifecycleStateRequest表示执行transaction后的最终的生命周期状态。
继续看处理ActivityThread.H.EXECUTE_TRANSACTION这个消息的处理,即TransactionExecutor的execute方法:
1 public void execute(ClientTransaction transaction) {
2 if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");
3
4 final IBinder token = transaction.getActivityToken();
5 ...
6 executeCallbacks(transaction);
7
8 executeLifecycleState(transaction);
9 ...
10 }
前面我们关注的是executeCallbacks方法,现在看看executeLifecycleState方法:
1 /** Transition to the final state if requested by the transaction. */
2 private void executeLifecycleState(ClientTransaction transaction) {
3 final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
4 if (lifecycleItem == null) {
5 // No lifecycle request, return early.
6 return;
7 }
8
9 final IBinder token = transaction.getActivityToken();
10 final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
11 ...
12
13 // Execute the final transition with proper parameters.
14 lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
15 lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
16 }
这里取出了ActivityLifecycleItem并且调用了它的execute方法,实际就是ResumeActivityItem的方法:
1 @Override
2 public void execute(ClientTransactionHandler client, IBinder token,
3 PendingTransactionActions pendingActions) {
4 Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
5 client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
6 "RESUME_ACTIVITY");
7 Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
8 }
经过上面分析实际是走到ActivityThread的handleResumeActivity方法:
1 @Override
2 public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
3 String reason) {
4 ...
5 // performResumeActivity内部会走onStart、onResume
6 final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
7 if (r == null) {
8 // We didn't actually resume the activity, so skipping any follow-up actions.
9 return;
10 }
11 ...
12
13 if (r.window == null && !a.mFinished && willBeVisible) {
14 r.window = r.activity.getWindow();
15 View decor = r.window.getDecorView();
16 decor.setVisibility(View.INVISIBLE);
17 ViewManager wm = a.getWindowManager();
18 WindowManager.LayoutParams l = r.window.getAttributes();
19 a.mDecor = decor;
20 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
21 l.softInputMode |= forwardBit;
22 if (r.mPreserveWindow) {
23 a.mWindowAdded = true;
24 r.mPreserveWindow = false;
25
26 ViewRootImpl impl = decor.getViewRootImpl();
27 if (impl != null) {
28 impl.notifyChildRebuilt();
29 }
30 }
31 ...
32
33 if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {
34 if (r.newConfig != null) {
35 performConfigurationChangedForActivity(r, r.newConfig);
36 if (DEBUG_CONFIGURATION) {
37 Slog.v(TAG, "Resuming activity " + r.activityInfo.name + " with newConfig "
38 + r.activity.mCurrentConfig);
39 }
40 r.newConfig = null;
41 }
42 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" + isForward);
43 WindowManager.LayoutParams l = r.window.getAttributes();
44 if ((l.softInputMode
45 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
46 != forwardBit) {
47 l.softInputMode = (l.softInputMode
48 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
49 | forwardBit;
50 if (r.activity.mVisibleFromClient) {
51 ViewManager wm = a.getWindowManager();
52 View decor = r.window.getDecorView();
53 wm.updateViewLayout(decor, l);
54 }
55 }
56
57 r.activity.mVisibleFromServer = true;
58 mNumVisibleActivities++;
59 if (r.activity.mVisibleFromClient) {
60 //添加window、设置可见
61 r.activity.makeVisible();
62 }
63 }
64
65 r.nextIdle = mNewActivities;
66 mNewActivities = r;
67 if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r);
68 Looper.myQueue().addIdleHandler(new Idler());
69 }
handleResumeActivity做了以下事情:
通过performResumeActivity方法,内部调用生命周期onStart、onResume(可以自行查看,这里不再扩展)
通过activity.makeVisible方法,添加window、设置可见。(所以视图的真正可见是在onResume方法之后)
好了,到这里就是真正创建完成并且可见了。
总结
关于Activity启动的流程的讲解,我们分成了几个阶段:启动的发起、AMS的管理、线程切换、启动核心实现,知道了启动过程经历了两次IPC,客户端到AMS、AMS到客户端,以及Activity创建和生命周期的执行。
好了,今天就到这里,欢迎留言讨论~
END
往期推荐
“终于懂了”系列:APK安装过程 完全解析!
“终于懂了” 系列:Android屏幕刷新机制—VSync、Choreographer 全面理解!
一文彻底搞懂Android View的绘制流程
Android触摸事件传递机制
欢迎关注我的微信:bcce5360,群人数已超200,无法扫码入群,加我微信拉你进群。
点击下方卡片关注JsonChao,为你构建一套
未来Android开发必备的知识体系
▲ 点击上方卡片关注 JsonChao,构建一套
未来 Android 开发必备的知识体系
欢迎把文章分享到朋友圈
很感谢您阅读这篇文章,希望您能将它分享给您的朋友或技术群,这对我意义重大。
你若喜欢,为JsonChao点个在看哦