美文网首页
源码解读|Activity 的启动流程(API 29)

源码解读|Activity 的启动流程(API 29)

作者: 南子李 | 来源:发表于2020-08-18 14:31 被阅读0次

    1. 前言

    由于系统极强的封装特性,我们在启动 Activity 时并不知道系统内部都是如何完成整个的启动流程的?如何创建一个 Activity 对象?什么时候调用 onCreate() 方法的?
    本文中所有源码都是基于 Android API 29。

    2. Activity 的启动方式

    Activity 的启动可以通过 startActivity() 或者 startActivityForResult(),两者的区别在于是否要接收来自被启动 Activity 的返回结果。

            Intent intent = new Intent(activity, CaptureActivity.class);
            activity.startActivity(intent);  //不接收来自 CaptureActivity 的返回结果
    
            Intent intent = new Intent(activity, CaptureActivity.class); //接收来自 CaptureActivity 的返回结果
            activity.startActivityForResult(intent, REQUEST_CAPTURE);
    

    3. 源码解析

    3.1 启动 Activity

    无论我们是通过 startActivity() 各种重载的方法还是通过 startActivityForResult() 方法启动 Activity,最后都会调用 Activity 的 startActivityForResult(Intent intent, int requestCode, Bundle options)。Context 是一个抽象类,有抽象方法 startActivity,ContextWrapper 继承自 Context ,是 Context 的代理类,实现了 startActivity;Activity 继承自 ContextWrapperTheme,ContextWrapperTheme 继承自 ContextWrapper,所以最终在 Activity 中实现的 startActivity 实际上是抽象类 Context 中的 startActivity 方法。

    • startActivityForResult()
        public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
                @Nullable Bundle options) {
            if (mParent == null) {
                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());
                }
                if (requestCode >= 0) {
                   mStartedActivity = true;
                }
    
                cancelInputsAndStartExitTransition(options);
           } else {
                if (options != null) {
                    mParent.startActivityFromChild(this, intent, requestCode, options);
                } else {
                    mParent.startActivityFromChild(this, intent, requestCode);
                }
            }
        }
    

    1)mParent,是一个 Activity 对象,表示当前 Activity 的父 Activity,判断 mParent 是否为空,为空直接执行步骤4,不为空执行2,3;
    2)mInstrumentation.execStartActivity,调用了 Instrumentation 的 execStartActivity 方法;
    3)mMainThread.sendActivityResult,如果步骤2中返回结果不为空,调用ActivityThread 的 sendActivityResult 方法;
    4)mParent 为空,调用父 Activity 的 startActivityFromChild 方法;

    先来看看步骤2中 Instrumentation 的 execStartActivity 方法,在这里利用了 Binder 机制,跨进程调用了 ATMS(ActivityTaskManagerService)的 startActivity 方法,ATMS 运行在系统服务进程中。

    public ActivityResult execStartActivity(
                Context who, IBinder contextThread, IBinder token, Activity target,
                Intent intent, int requestCode, Bundle options) {
            IApplicationThread whoThread = (IApplicationThread) contextThread;
            ...
            try {
                intent.migrateExtraStreamToClipData();
                intent.prepareToLeaveProcess(who);
                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;
        }
    

    1)ActivityTaskManager.getService().startActivity 即是调用了 ATMS 的 startActivity 方法;
    2)checkStartActivityResult(),检查启动 Activity 的结果。
    先来看 checkStartActivityResult 方法,主要是检查启动 Activity 的结果,有异常则抛出。例如下面代码中是一个典型的未找到启动 Activity 的异常,因为我们没有在 AndroidManifest 文件中声明我们的 Activity。

    public static void checkStartActivityResult(int res, Object intent) {
            if (!ActivityManager.isStartResultFatalError(res)) {
                return;
            }
    
            switch (res) {
                case ActivityManager.START_INTENT_NOT_RESOLVED:
                case ActivityManager.START_CLASS_NOT_FOUND:
                    if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
                        throw new ActivityNotFoundException(
                                "Unable to find explicit activity class "
                                + ((Intent)intent).getComponent().toShortString()
                                + "; have you declared this activity in your AndroidManifest.xml?");
                    throw new ActivityNotFoundException(
                            "No Activity found to handle " + intent);
                ...
            }
        }
    

    接着来看 ActivityTaskManager 的 getService 方法:

    • ActivityTaskManager
        public static IActivityTaskManager getService() {
            return IActivityTaskManagerSingleton.get();
        }
        private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
                new Singleton<IActivityTaskManager>() {
                    @Override
                    protected IActivityTaskManager create() {
                        final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
                        return IActivityTaskManager.Stub.asInterface(b);
                    }
                };
    

    这里是通过 Singleton 返回了一个 IActivityTaskManager 对象,Singleton 是一个单例的封装类,第一次调用它的get 方法时它会通过 create 方法来初始化一个 IActivityTaskManager,IActivityTaskManager 其实是一个 Binder 对象,负责应用和 ActivityTaskManagerService (以下简称 ATMS)直接的通信。
    ATMS 运行在服务进程(system_server)中,Instrumentation 实现了应用和 ATMS 之间的通信,Activity 的启动就转移到了 ATMS 中:

    • ActivityTaskManagerService

    ATMS 中 startActivity 方法调用了 startActivityAsUser 方法,startActivityAsUser 调用了 ActivityStarter 的 execute 方法。

        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) {
            userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
                    Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
            return 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();
        }
    

    getActivityStartController() 获取到 ActivityStarController 对象,调用 ActivityStarController 的 obtainStarter() 获取 ActivityStarter 对象,ActivityStart 设置一些需要传给应用进程的信息,然后调用了 ececute 方法。

    • ActivityStarter

    execute 方法根据启动请求调用 startActivityMayWait 方法或者 startActivity 方法,直接来看 startActivity 方法,startActivity 方法调用了 startActivityUnchecked 方法,startActivityUnchecked 调用了 ActivityTask 的 sendActivityResultLocked 方法。

    //ActivityStarter
        int execute() {
            try {
                if (mRequest.mayWait) {
                    return startActivityMayWait(...);
                } else {
                    return startActivity(...);
                }
            } finally {
                onExecutionComplete();
            }
        }
        private ActivityStack mTargetStack;
    //ActivityStarter#startActivityUnchecked()
        mTargetStack.startActivityResultLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
                    mOptions);
    
    • ActivityTask

    sendActivityResultLocked 方法通过 ActivityTaskManagerService 调用了 ClientLifecycleManager 的 scheduleTransaction 方法

        void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            final IApplicationThread client = transaction.getClient();
            transaction.schedule();
            if (!(client instanceof Binder)) {
                transaction.recycle();
            }
        }
    

    scheduleTransaction 方法通过 ClientTransaction 的 schedule 方法调用了 IApplicationThread 的 scheduleTransaction 方法。

        private IApplicationThread mClient;
        public void schedule() throws RemoteException {
            mClient.scheduleTransaction(this);
        }
    
    • IApplicationThread 和 ApplicationThread

    IApplicationThread 继承了 IInterface 接口,它是一个 Binder 类型的接口,IApplicationThread 的最终实现类是 ActivityThread 的内部类 ApplicationThread。ApplicationThread 继承自 ApplicationThreadNative,ApplicationThreadNative 继承自 Binder 并实现来 IApplicationThread 接口。ApplicationThreadNative 的作用和使用 AIDL 时系统生成的类是一样,它的内部有一个 ApplicationThreadProxy 类,这个类也就是 AIDL 文件的代理类。综上所述,IApplicationThread 的实现类就是 ApplicationThreadNative,而 ApplicationThreadNative 被定义为了抽象类,那最终实现者就是 ApplicationThread。

    • ActivityThread

    ApplicationThread 的 scheduleTransaction 方法调用了 ActivityThread 的 scheduleTransaction 方法,ActivityThread 继承自 ClientTransactionHandler,ClientTransactionHandler 是抽象类,它的 scheduleTransaction 方法中调用 sendMessage 方法发送了一条 EXECUTE_TRANSACTION 类型的消息,sendMessage 是抽象方法,ActivityThread 实现了该方法,ActivityThread 的 sendMessage 方法中将要发送的消息封装在 Message 中,通过 ActivityThread 的 H 对象 mH 执行了消息的发送,H 是 ActivityThread 的静态内部类,继承自 Handler,用于接收并处理来自其他线程的消息。

    //ClientTransactionHandler
        void scheduleTransaction(ClientTransaction transaction) {
            transaction.preExecute(this);
            sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
        }
        abstract void sendMessage(int what, Object obj);
    //ActivityThread
        private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
            ...
            Message msg = Message.obtain();
            msg.what = what;
            msg.obj = obj;
            msg.arg1 = arg1;
            msg.arg2 = arg2;
            if (async) {
                msg.setAsynchronous(true);
            }
            mH.sendMessage(msg);
        }
    

    ActivityThread 中,H 收到 EXECUTE_TRANSACTION 类型的消息,调用 TransactionExecutor 的 execute 方法,execute 方法调用了 executeCallbacks 方法,executeCallbacks 中调用 LaunchActivityItem 的 execute 方法,LaunchActivityItem 继承自 ClientTransactionItem 并实现了 execute 方法,execute 方法调用了 ClientTransactionHandler 的 handleLaunchActivity 方法,ActivityThread 继承自 ClientTransactionHandler ,并实现了 handleLaunchActivity 方法,这里又回到了 ActivityThread 中的 handleLaunchActivity 方法内,handleLaunchActivity 方法调用了 performLaunchActivity 方法。

    • performLaunchActivity 方法:

    1)从 ActivityClientRecord 中获取待启动 Activity 的启动信息;
    2)调用 createBaseContextForActivity 方法创建 ContextImpl 对象,该方法中调用 ContextImpl 的 createActivityContext 方法创建 ContextImpl 对象;

        ContextImpl appContext = createBaseContextForActivity(r);
    
        private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
           ...
            ContextImpl appContext = ContextImpl.createActivityContext(
                    this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);
            ...
            return appContext;
        }
    

    3)调用 Instrumentation 的 newActivity 方法新建并加载 Activity,newActivity 方法中调用 AppComponentFactory 的 instantiateActivity方法,instantiateActivity 方法通过在 performLaunchActivity 方法中新建的 ClassLoader 加载新建的 Activity 类;

        activity = mInstrumentation.newActivity(cl,component.getClassName(),r.intent);
    
    //Instrumentation
        public Activity newActivity(ClassLoader cl, String className,
                Intent intent)
                throws InstantiationException, IllegalAccessException,
                ClassNotFoundException {
            String pkg = intent != null && intent.getComponent() != null
                    ? intent.getComponent().getPackageName() : null;
            return getFactory(pkg).instantiateActivity(cl, className, intent);
        }
    //AppComponentFactory
        public @NonNull Activity instantiateActivity(@NonNull ClassLoader cl, @NonNull String className,
                @Nullable Intent intent)
                throws InstantiationException, IllegalAccessException, ClassNotFoundException {
            return (Activity) cl.loadClass(className).newInstance();
        }
    

    4)通过 LoadApk 的 makeApplication 方法创建一个 Application 对象;

       Application app = r.packageInfo.makeApplication(false, mInstrumentation);
    //r.packageInfo 就是 ActivityClientRecord 中存的 LoadApk 对象
    

    5)调用 Activity 的 attach 方法,ContextImpl 通过 Activity 的 attach 方法来和 Activity 建立关联,除此之外,attach 方法还完成了 Window 的创建并建立自己和 Window 的关联,这样当 Window 接收到外部输入事件后就可以将事件传递给 Activity;

       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,
                            r.assistToken);
    //Activity的attatch
            //将创建的 Activity 和 ContextImpl
            attachBaseContext(context); 建立关联
            //为新建的 Activity 创建 Window,用于接收到外部输入事件后将事件传给Activity
            mWindow = new PhoneWindow(this, window, activityConfigCallback);
            mWindow.setWindowControllerCallback(this);
            mWindow.setCallback(this);
            mWindow.setOnWindowDismissedCallback(this);
            mWindow.getLayoutInflater().setPrivateFactory(this);
    

    6)调用 Instrumentation 的 callActivityOnCreate 方法,callActivityOnCreate 方法调用 Activity 的 performCreate 方法,performCreate 调用 onCreate 方法。

        mInstrumentation.callActivityOnCreate(activity, r.state);
    //Instrumentation
        public void callActivityOnCreate(Activity activity, Bundle icicle) {
            prePerformCreate(activity);
            activity.performCreate(icicle);
            postPerformCreate(activity);
        }
    //Activity
        final void performCreate(Bundle icicle, PersistableBundle persistentState) {
            ...
            if (persistentState != null) {
                onCreate(icicle, persistentState);
            } else {
                onCreate(icicle);
            }
            ...
        }
    

    至此走完了从发起启动 Activity 的请求、Activity 的创建、Activity 的加载到最后调用 onCreate 方法的整个流程。这里只是分析整个的流程大概,涉及到启动模式等的细节没有去探讨。

    4. 总结

    4.1 重要类
    • Instrumentation:管理应用进程和系统进程之间的通信;
    • ActivityTaskManager:实现应用进程和运行在系统进程的 ActivityTaskManagerService 的通信;
    • ActivityTaskManagerService:负责管理activity;
    • ActivityStarter:负责启动模式,启动Flag相关处理;
    • ActivityStack:负责管理单独栈的 Activity 和其状态,即具体启动的执行等;
    • ApplicationThread(IApplicationThread):继承自 IApplicationThread,会在 ActivityTask 中调用,处理 Activity、Service、Broadcast 的创建等操作;
    • ActivityThread(ClientTransactionHandler):继承自 ClientTransactionHandler,管理应用进程中主线程,执行和调度 Activity、广播,处理来自 Activity 的任务请求;
    • ActivityClientRecord:保存和 Activity 相关的参数信息,还保存了和 Activity 关联的 Window 的信息;
    4.2 完整流程图
    Activity 启动流程图.png

    5. 参考

    相关文章

      网友评论

          本文标题:源码解读|Activity 的启动流程(API 29)

          本文链接:https://www.haomeiwen.com/subject/jxdtjktx.html