写点什么

Activity 启动流程分析 (android-29),Android 面试题库

用户头像
Android架构
关注
发布于: 11 小时前

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


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


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 进程处理;

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Activity启动流程分析(android-29),Android面试题库