Activity 启动流程分析 (android-29),Android 面试题库
2. ServiceManager
ServiceManager 负责把 Binder Server 注册到一个容器中,这样当有 Client 进程想与 Server 进程通信时,ServiceManager 就可以从查找表中找到 Binder Server,并返回 Binder Server 的代理对象给 Client 进程。
3. ActivityManagerService
ActivityManagerService 是一个系统服务进程,四大组件的启动方式都是通过 binder 的方式与 ActivityManagerService 通信完成的;
ActivityManagerService 将自己注册到 ServiceManager 的代码如下(本文分析基于 android-29 源码):
public class ActivityManagerService extends IActivityManager.Stub {public void setSystemProcess() {ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);}}
注册完成之后,其他进程就可通过如下方式获得 ActivityManagerService 的代理:
public class ActivityManager {public static IActivityManager getService() {return IActivityManagerSingleton.get();}private static final Singleton<IActivityManager> IActivityManagerSingleton =new Singleton<IActivityManager>() {@Overrideprotected IActivityManager create() {final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);final IActivityManager am = IActivityManager.Stub.asInterface(b);return am;}};}
以上代码,可以看出 ActivityManager 封装了对 ActivityManagerService 的调用,通过 ActivityManager.gerService()即可获得对 ActivityManagerService 的调用。
4. ActivityThread、ApplicationThread 傻傻分不清楚
ActivityThread 就是 UI 线程,是在 APP 启动时创建的;它包含一个 static 的 main()方法如下所示(后面会详细分析):
public final class ActivityThread{// 后面会重点分析 Instrumentation mInstrumentation;
public static void main(String[] args) {// 省略部分代码...Looper.prepareMainLooper();// ...ActivityThread thread = new ActivityThread();thread.attach(false, startSeq);// ...Looper.loop();}
private void attach(boolean system, long startSeq) {mInstrumentation = new Instrumentation();// ...mInstrumentation.basicInit(this);ContextImpl context = ContextImpl.createAppContext(this, getSystemContext().mPackageInfo);mInitialApplication = context.mPackageInfo.makeApplication(true, null);}}
ApplicationThread 是 ActivityThread 的内部类,并不是一个线程,可用来代表当前 APP 进程(可能这就是它叫 Thread 的原因吧),由以下代码可分析出 app 间进程通信时,获得另一个 app 进程也是通过 binder 来获取其代理实现的;
private class ApplicationThread extends IApplicationThread.Stub {// 省略部分代码...}
5. Instrumentation
instrumentation 英 [??nstr?men?te??n] 美 [??nstr?men?te??n]
n.(一套)仪器,仪表;器乐谱写
Instrumentation 源码解释如下:
/**
Base class for implementing application instrumentation code. When running
with instrumentation turned on, this class will be instantiated for you
before any of the application code, allowing you to monitor all of the
interaction the system has with the application. An Instrumentation
implementation is described to the system through an AndroidManifest.xml's
<instrumentation> tag.*/
可以大概理解为所有与 application 有关的调用都会通过 Instrumentation 这样一个仪器来方便地观察到;换句话说就是,所有有关 application 的调用实际上都会通过 Instrumentation;看一下其源码就可以看到它里面完成了许多功能:
public class Instrumentation {private ActivityThread mThread = null;private MessageQueue mMessageQueue = null;private List<ActivityMonitor> mActivityMonitors;
public Application newApplication(ClassLoader cl, String className, Context context) {}
public Activity newActivity(ClassLoader cl, String className,Intent intent) {}
public void callActivityOnNewIntent(Activity activity, Intent intent) {}
public ActivityResult execStartActivity(){}
}
二、Activity 启动流程分析
例如 App1 要启动 App2 的一个 Activity;Activity 启动流程分析如下:
1. App1 中的 SampleActivity1 启动 App2 的 SampleActivity2
public class SampleActivity1 {public void onClick() {Intent intent = getPackageManager().getLaunchIntentForPackage("com.app2.sample");startActivity(intent);}}
2. Activity 源码分析
public class Activity {public void startActivity(Intent intent) {this.startActivity(intent, null);}
public void startActivity(Intent intent, @Nullable Bundle options) {// ...startActivityForResult(intent, -1);}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) {// 省略部分代码...options = transferSpringboardActivityOptions(options);Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options);if (ar != null) {mMainThread.sendActivityResult(mToken, mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData());}}}
可以看到,Activity 的 startActivity 最终都调用到了 Instrumentation 里面;
3. Instrumentation 源码分析
继续分析 Instrumentation 的 execStartActivity()方法:
public class Instrumentation {/**
可以看到传递的参数中比较重要的几个:
context who:就是前面的 SampleActivity1
IBinder contextThread:传的 value 是 mMainThread.getApplicationThread(),即当前 APP 进程,这样 AMS 进程才可以通过 IBinder 与 App1 进程通信(比如将结果返回,就需要 binder 通信)
IBinder token:又见 IBinder,那一定也是别的进程需要通过这个 IBinder 进行通信
Intent intent:启动参数**/public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target,Intent intent, int requestCode, Bundle options) {IApplicationThread whoThread = (IApplicationThread) contextThread;// 省略部分代码...try {int result = ActivityTaskManager.getService().startActivity(whoThread, who.getBasePackageName(), intent,intent.resolveTypeIfNeeded(who.getContentResolver()),token, target != null ? target.mEmbeddedID : null,requestCode, 0, null, options);checkStartActivityResult(result, intent);} catch (RemoteException e) {throw new RuntimeException("Failure from system", e);}return null;}}
可以看到,又继续调用到了 ActivityTaskManager.getService().startActivity()里面。
ps. 在 android-28 源码中是调用到了 ActivityManager.getService().startActivity()里面,更老版本 android 源码中是调用了 ActivityManagerNative.getDefault(),原理都类似,都是调用返回一个代理,最终到了系统进程去执行后续调起逻辑。
4. ActivityTaskManager 源码分析
@SystemService(Context.ACTIVITY_TASK_SERVICE)public class ActivityTaskManager {public static IActivityTaskManager getService() {return IActivityTaskManagerSingleton.get();}
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =new Singleton<IActivityTaskManager>() {@Overrideprotected IActivityTaskManager create() {final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);return IActivityTaskManager.Stub.asInterface(b);}};}
可以看出,ActivityTaskManager.getService()调用得到 IBinder 的 proxy 继续执行后续代码,这样就就调用到了系统进程里面继续执行;ActivityTaskManager 是系统启动期间就注册的一个 binder service,其注册代码如下:
@SystemApipublic final class SystemServiceRegistry {static {registerService(Context.ACTIVITY_TASK_SERVICE, ActivityTaskManager.class,new CachedServiceFetcher<ActivityTaskManager>() {@Overridepublic ActivityTaskManager createService(ContextImpl ctx) {return new ActivityTaskManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());}});}
接下来继续分析系统进程中 startActivity()的执行步骤;
5. ActivityTaskManagerService 源码分析
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {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());}
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) {// 省略部分代码...// getActivityStartController().obtainStarter 返回一个 ActivityStarter 对象,下面继续分析 ActivityStarterreturn getActivityStartController().obtainStarter(intent, "startActivityAsUser").setCaller(caller).setCallingPackage(callingPackage).setResolvedType(resolvedType).setResultTo(resultTo).setResultWho(resultWho).setRequestCode(requestCode).setStartFlags(startFlags).setProfilerInfo(profilerInfo).setActivityOptions(bOptions).setMayWait(userId).execute();
}}
6. ActivityStarter 源码分析
ActivityStarter 负责处理 intent 中 flag、启动模式等参数;
class ActivityStarter {int execute() {try {// ...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,mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);} finally {onExecutionComplete();}}
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,ActivityRecord[] outActivity, boolean restrictedBgActivity) {int result = START_CANCELED;final ActivityStack startedActivityStack;try {mService.mWindowManager.deferSurfaceLayout();result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);}// ...}
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,ActivityRecord[] outActivity, boolean restrictedBgActivity) {// ...mRootActivityContainer.resumeFocusedStacksTopActivities();}}
接下里继续到 RootActivityContainer;
/**
Root node for activity containers.
TODO: This class is mostly temporary to separate things out of ActivityStackSupervisor.java. The
intention is to have this merged with RootWindowContainer.java as part of unifying the hierarchy.
看样子这个类后面可能会被合入到 RootWindowContainer 里,不重点分析;*/class RootActivityContainer {boolean resumeFocusedStacksTopActivities(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {if (targetStac
k != null && (targetStack.isTopStackOnDisplay() || getTopDisplayFocusedStack() == targetStack)) {result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);}}}
7. ActivityStack 源码分析
ActivityStack 负责管理 activity 栈和 activity 的状态,包括根据 activity 栈的状态决定如何管理 activity 等,当然 activity 的启动也是由它来继续完成;
/**
State and management of a single stack of activities.*/class ActivityStack extends ConfigurationContainer {boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {if (mInResumeTopActivity) {// Don't even start recursing.return false;}
boolean result = false;try {// Protect against recursion.mInResumeTopActivity = true;result = resumeTopActivityInnerLocked(prev, options);}}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {// ...if (next.attachedToProcess()) {if (nextNext != next) {// Do over!mStackSupervisor.scheduleResumeTopActivities();}} else {// Whoops, need to restart this activity!mStackSupervisor.startSpecificActivityLocked(next, true, true);}}}
8. StackSupervisor 源码分析
// TODO: This class has become a dumping ground. Let's// - Move things relating to the hierarchy to RootWindowContainer// - Move things relating to activity life cycles to maybe a new class called ActivityLifeCycler// - Move interface things to ActivityTaskManagerService.// - All other little things to other files.// 看样子这部分代码后面也会被 RootWindowContainer 里面,后面 Android 源码分析可能要重点分析这个类了 ??public class ActivityStackSupervisor implements RecentTasks.Callbacks {
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {// Is this activity's application already running?final WindowProcessController wpc =mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;if (wpc != null && wpc.hasThread()) {try {// 重点分析 realStartActivityLocked(r, wpc, andResume, checkConfig);return;} catch (RemoteException e) {Slog.w(TAG, "Exception when starting activity "
r.intent.getComponent().flattenToShortString(), e);}
// If a dead object exception was thrown -- fall through to// restart the application.knownToBeDead = true;}}
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc, boolean andResume, boolean checkConfig) {// ...// Create activity launch transactionfinal ClientTransaction clientTransaction = ClientTransaction.obtain( proc.getThread(), r.appToken);// 重点,这里先记住它的 callback 是 LaunchActivityItemclientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),System.identityHashCode(r), r.info,// TODO: Have this take the merged configuration instead of separate global// and override configs.mergedConfiguration.getGlobalConfiguration(),mergedConfiguration.getOverrideConfiguration(), r.compat,r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),r.icicle, r.persistentState, results, newIntents,dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),r.assistToken));// Schedule transaction. mService 就是 ActivityTaskManagerServicemService.getLifecycleManager().scheduleTransaction(clientTransaction);}}
以上代码分析出,启动 activity 被封装成 transaction 由 ActivityTaskManagerService 中的 ClientLifecycleManager 进程处理;
评论