主要对象介绍
- ActivityManagerService:负责系统中所有Activity的生命周期;
- ActivityThread:App的真正入口,当App启动后,会调用其main方法开始执行,开启消息循环队列。是传说中的UI线程,即主线程。与ActivityManagerService配合,一起完成Activity的管理工作;
- ApplicationThread:用来实现ActivityManagerService与ActivityThread之间的交互。在ActivityManagerService需要管理相关Application中的Activity的生命周期,通过ApplicationThread的代理对象与ActivityThread通讯;
- ApplictationThreadProxy:是ApplicationThread在服务端的代理对象,负责和客户端的ApplicationThread通讯。AMS就是通过这个代理对象与ActivityThread进行通信的,Android 8.0上以删除该类,采用AIDL接口的方式来进行IPC,实现RPC操作;
- Instrumentation:每一个应用程序都只有一个Instrumentation对象,每个Activity内都有一个对该对象的引用。Instrumentation可以理解为应用进程的管家,ActivityThread要创建或者打开某个Activity时,都需要通过Instrumentation来进行具体的操作;
- ActvitityStack:Activity在AMS的栈管理,用来记录已经启动的Activity的先后关系、状态信息等。通过ActivityStack决定是否需要启动新的进程;
- ActivityRecord:ActivityStatck的管理对象,每个Activity在AMS对应的一个ActivityRecord,来记录Activity的状态以及其他信息。可以理解为Activity在服务端的Activity对象的映射;
- ActivityClientRecord:与ActivityRecord是在服务端(AMS)的记录相对应,是Activity在客户端(ActivityThread)的记录;
- TaskRecord:AMS抽象出来的任务栈的概念。一个TaskRecord包含若干个ActivityRecord。ASM用它来确保Activity启动和退出顺序。它与Activity的启动模式直接相关。
- ActivityStarter:启动Activity的控制器,主要用于用来将Intent和flags转换成activity和相关任务栈;
- ActivityStackSupervisor:主要管理着mHomeStack和mFocusedStack两个ActivityStack等相关信息;
Binder通信
- 在Android 8.0以前,Binder通信的流程如下:
客户端: ActivityManagerProxy -> Binder驱动 -> 服务端:ActivityManagerService
服务端: ApplicationThreadProxy -> Binder驱动 -> 客户端:ApplicationThread - Android8.0开始,删除了ActivityManagerNative,AMS的继承类也发生了变化,继承了IActivityManager.Stub接口类。了解Android的Binder机制应该知道,这里IActivityManager.aidl生成的接口类。Android8.0开始,把一些Binder代码转化为了AIDL模板方式:
- public class ActivityManagerService extends IActivityManager.Stub
- implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback
ActivityManager中的代码:
- 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;
- }
- };
- 而在Android7.0及其以前的版本上,则是客户端通过ActivityManaagerProxy与服务端的ActivityManager进行通信的
ActivityManagerNative:
- **
- *获得IActivityManager类
- */
- static public IActivityManager getDefault() {
- return gDefault.get();
- }
-
- static public IActivityManager asInterface(IBinder obj) {
- if (obj == null) {
- return null;
- }
- IActivityManager in =
- (IActivityManager)obj.queryLocalInterface(descriptor);
- if (in != null) {
- return in;
- }
-
- return new ActivityManagerProxy(obj);
-
- }
ActivityManager:
- private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
- protected IActivityManager create() {
- IBinder b = ServiceManager.getService("activity");
- if (false) {
- Log.v("ActivityManager", "default service binder = " + b);
- }
- IActivityManager am = asInterface(b);//注意这一行
- if (false) {
- Log.v("ActivityManager", "default service = " + am);
- }
- return am;
- }
- };
可以看出来,两个写法不一样,本质上都是一样的,Android 8.0可能使用了AIDL方式进行ipc。
- 同理,ApplicationThread同上述一样做了更改:
- private class ApplicationThread extends IApplicationThread.Stub {
- ...
- }
所以在Android 8.0上不存在ActivityManagerProxy和ApplicationThreadProxy,而是采用了AIDL接口的方式来进行通信的。
源码调用栈(基于Android 8.0)
按照自上而下的调用栈的顺序进行调用,以类文件为单位来计步,方便大家去了解调用流程,主要涉及的几个源文件:Instumentation,ActivityMangerService,ActivityStack,ActivityStarter,ActivityStackSupervisor,ActivityThread,Activity等。
- Activity
- public void startActivity(Intent intent)
-
- public void startActivity(Intent intent, @Nullable Bundle options)
-
- public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
- @Nullable Bundle options)
- Intrumentation
- public ActivityResult execStartActivity(
- Context who, IBinder contextThread, IBinder token, Activity target,
- Intent intent, int requestCode, Bundle options){
- ...
- int result = ActivityManager.getService()
- .startActivity(whoThread, who.getBasePackageName(), intent,
- intent.resolveTypeIfNeeded(who.getContentResolver()),
- token, target != null ? target.mEmbeddedID : null,
- requestCode, 0, null, options);
- ...
- }
- ActivityManagerService
- 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());
- }
-
-
- 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) {
- ...
- return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
- resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
- profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
- }
- ActivityStarter
- final 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, Bundle bOptions, boolean ignoreTargetSecurity,
- int userId,askRecord inTask, String reason) {
- ...
- int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
- aInfo, rInfo, voiceSession, voiceInteractor,
- resultTo, resultWho, requestCode, callingPid,
- callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
- options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,
- reason);
- ...
- }
-
-
- int startActivityLocked(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,
- ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
- ActivityRecord[] outActivity, TaskRecord inTask, String reason) {
- ...
- mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
- aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
- callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
- options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
- inTask);
- ...
- }
-
- 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,
- ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
- ActivityRecord[] outActivity, TaskRecord inTask) {
- ...
- doPendingActivityLaunchesLocked(false);
- return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
- options, inTask, outActivity);
- }
-
-
- private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
- IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
- int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
- ActivityRecord[] outActivity) {
- ...
- result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
- startFlags, doResume, options, inTask, outActivity);
- ...
- }
-
- private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
- IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
- int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
- ActivityRecord[] outActivity) {
- ...
- if (mDoResume) {
- mSupervisor.resumeFocusedStackTopActivityLocked();
- }
- ...
- }
- ActivityStackSupervisor
- boolean resumeFocusedStackTopActivityLocked() {
- return resumeFocusedStackTopActivityLocked(null, null, null);
- }
-
- boolean resumeFocusedStackTopActivityLocked(
- ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
- ...
- if (r == null || r.state != RESUMED) {
- mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
- }
- ...
- }
- ActivityStack
- boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
- ...
- result = resumeTopActivityInnerLocked(prev, options);
- ...
- }
-
- private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
- ....
- if (mResumedActivity != null) {
- //同步等待pause当前Activity的结果
- pausing |= startPausingLocked(userLeaving, false, next, false);
- }
- ....
- //开始启动下一个Activity
- mStackSupervisor.startSpecificActivityLocked(next, true, false);
- ....
- }
-
-
- final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming, boolean pauseImmediately) {
- ....
- //去当前Activity所在应用进程暂停当前activity
- prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
- userLeaving, prev.configChangeFlags, pauseImmediately);
- ....
- }
-
- ActivityThread$ApplicationThread
- public final void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges, boolean dontReport) {
- ...
- sendMessage(finished ? H.PAUSE_ACTIVITY_FINISHING: H.PAUSE_ACTIVITY, token,
- (userLeaving ? USER_LEAVING: 0) | (dontReport ? DONT_REPORT: 0), configChanges, seq);
- ...
- }
- ActivityThread
- private void sendMessage(int what, Object obj, int arg1, int arg2, int seq) {
- Message msg = Message.obtain();
- ....
- mH.sendMessage(msg);
- }
- ActivityThread$H
- public void handleMessage(Message msg) {
- ...
- switch (msg.what) {
- case PAUSE_ACTIVITY:
- {
- SomeArgs args = (SomeArgs) msg.obj;
- handlePauseActivity((IBinder) args.arg1, false, (args.argi1 & USER_LEAVING) != 0,
- args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3);
- }
- break;
- }
- ...
- }
- ActivityThread
- private void handlePauseActivity(IBinder token, boolean finished,
- boolean userLeaving, int configChanges, boolean dontReport, int seq) {
- ...
- performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");
- ...
- //执行完后通知AMS当前Activity已经pause
- ActivityManager.getService().activityPaused(token);
- ...
- }
-
- final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
- boolean saveState, String reason) {
- ...
- performPauseActivityIfNeeded(r, reason);
- ...
- }
-
-
- private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
- ...
- mInstrumentation.callActivityOnPause(r.activity);
- ...
- }
- Instrumentation
- public void callActivityOnPause(Activity activity) {
- activity.performPause();
- }
- Activity
- final void performPause() {
- ...
- onPause();
- ...
- }
由于在ActivityThread中handlePauseActivity的方法里,在pause成功后,需要通知AMS已经pause成功,所以接着分析ActivityManagerService.activityPaused方法。
- ActivityManagerService
- public final void activityPaused(IBinder token) {
- final long origId = Binder.clearCallingIdentity();
- synchronized(this) {
- ActivityStack stack = ActivityRecord.getStackLocked(token);
- if (stack != null) {
- stack.activityPausedLocked(token, false);
- }
- }
- Binder.restoreCallingIdentity(origId);
- }
- ActivityStack
- final void activityPausedLocked(IBinder token, boolean timeout) {
- ...
- mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
- ...
- completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
- ...
- }
-
- private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
- ...
- mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
- ...
- }
- ActivityStackSupervisor
- boolean resumeFocusedStackTopActivityLocked(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
- //如果启动Activity和要启动的Activity在同一个ActivityStack中,调用targetStack对象的方法
- if (targetStack != null && isFocusedStack(targetStack)) {
- return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
- }
- //如果不在同一个ActivityStack中,则调用mFocusStack对象的方法
- if (r == null || r.state != RESUMED) {
- mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
- }
-
- return false;
- }
- ActivityStatck
- boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
- ...
- result = resumeTopActivityInnerLocked(prev, options);
- ...
- }
-
- private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
- ...
- if (mResumedActivity != null) {
- //同步等待pause当前Activity的结果,但在pause时,已经把mResumedActivity置为了null,所以不走这里
- pausing |= startPausingLocked(userLeaving, false, next, false);
- ...
- }
- ...
- return true;
- ...
- //开始启动下一个Activity
- mStackSupervisor.startSpecificActivityLocked(next, true, false);
- ...
- }
- ActivityStackSupervisor
- void startSpecificActivityLocked(ActivityRecord r,
- boolean andResume, boolean checkConfig) {
- if (app != null && app.thread != null) {
- ...
- realStartActivityLocked(r, app, andResume, checkConfig);
- return;
- }
- ...
- //启动跨进程的Activity需要先开启新的应用进程
- mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
- "activity", r.intent.getComponent(), false, false, true);
- }
-
- final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
- boolean andResume, boolean checkConfig) throws RemoteException {
- ...
- app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
- System.identityHashCode(r), r.info,
- // TODO: Have this take the merged configuration instead of separate global
- // and override configs.
- mergedConfiguration.getGlobalConfiguration(),
- mergedConfiguration.getOverrideConfiguration(), r.compat,
- r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
- r.persistentState, results, newIntents, !andResume,
- mService.isNextTransitionForward(), profilerInfo);
- ...
- }
- ActivityThread$ApplicationThread
- public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
- ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
- CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
- int procState, Bundle state, PersistableBundle persistentState,
- List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
- boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
- ...
- sendMessage(H.LAUNCH_ACTIVITY, r);
- }
- ActivityThread
- private void sendMessage(int what, Object obj) {
- sendMessage(what, obj, 0, 0, false);
- }
-
-
- private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
- ...
- mH.sendMessage(msg);
- }
-
- ActivityThread$H
- public void handleMessage(Message msg) {
- ...
- switch (msg.what) {
- case LAUNCH_ACTIVITY:
- {
- ....
- handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
- ....
- }
- break;
- ...
- }
- }
- ActivityThread
- private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
- ...
- Activity a = performLaunchActivity(r, customIntent);
- }
-
- private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent){
- ...
- if (r.isPersistable()) {
- mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
- } else {
- mInstrumentation.callActivityOnCreate(activity, r.state);
- }
- ...
- }
- Instumentation
- public void callActivityOnCreate(Activity activity, Bundle icicle) {
- prePerformCreate(activity);
- activity.performCreate(icicle);
- postPerformCreate(activity);
- }
- Activity
- final void performCreate(Bundle icicle) {
- performCreate(icicle, null);
- }
-
- final void performCreate(Bundle icicle, PersistableBundle persistentState) {
- ...
- if (persistentState != null) {
- onCreate(icicle, persistentState);
- } else {
- onCreate(icicle);
- }
- ...
- }
Activity启动流程
为了叙述方便,我们假设Activity A要启动Activity B。
- Activity A向AMS发送一个启动Activity B的进程间通信请求;
- AMS会将要启动的Activity B的组件信息保存下来,然后通过Binder通信(ApplicationThread及其接口定义语言),让Activity A执行pause操作;
- Activity B完成pause操作后,通过Binder通信(ActivityManagerService及其接口定义语言)通知AMS,可以执行启动Activity B的操作了(要启动的activity信息保存在了栈顶);
- 在启动之前,如果发现Activity B的应用程序进程不存在,会先启动一个新的进程(上述调用栈没涉及,同学们可自行查看源码);
- AMS执行一系列启动Activity B的操作,并通过Binder通信(ApplicationThread及其接口定义语言)进行跨进程调用,将Activity B启动起来;
关于AMS
- AMS的启动是在SystemServer(系统进程)中启动的,同其他Android应用一样,也是由Zygote进程fork出来的:
- public final class SystemServer {
-
- /**
- * The main entry point from zygote.
- * 注释写的很清楚了,SystemServer进程是有Zygote进程fork出来的
- */
- public static void main(String[] args) {
- new SystemServer().run();
- }
-
- private void run() {
- ...
- startBootstrapServices();
- ...
- }
-
- private void startBootstrapServices() {
- ...
- // Activity manager runs the show.
- traceBeginAndSlog("StartActivityManager");
- //开启ActivityManagerService进程
- mActivityManagerService = mSystemServiceManager.startService(
- ActivityManagerService.Lifecycle.class).getService();
- mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
- mActivityManagerService.setInstaller(installer);
- traceEnd();
- ...
- }
- }
- AMS与APP进程的通信:
- APP进程通过IActivityManager.aidl接口向AMS进程进行通信。
ActivityManager.getService()获得AMS的Binder接口,再通过Stub.asInterface的方式,转成IActivityManager的接口,通过IActivityManager与AMS进行通信,实现RPC远程跨进程调用;
Instrumentation
- int result = ActivityManager.getService()
- .startActivity(whoThread, who.getBasePackageName(), intent,
- intent.resolveTypeIfNeeded(who.getContentResolver()),
- token, target, requestCode, 0, null, options);
ActivityManager
- 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;
- }
- };
-
- AMS进程通过IApplication.aidl接口向APP进程进行通信。
在AMS内部持有每个ActivityThread的IApplicatinThread接口实例,用时可以直接调用。同IActivityManager,也是通过Binder进行进程间通信。