美文网首页android 技术梳理
根 Activity 的启动后续

根 Activity 的启动后续

作者: jkwen | 来源:发表于2021-01-27 16:34 被阅读0次

    Lifecycle 和 Transaction

    在 API 28 里,启动 Activity 并不像之前那样,而是增加了 Lifecycle 概念,并通过事务来处理启动 Activity。

    //ActivityStackSupervisor
    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) {
        //create activity launch transaction
        final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread, r.appToken);
        //这里稍微留意,后面用得到
        clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),...));
        //这里是通过 lifecycle 这个概念来执行事务启动 Activity
        mService.getLifecycleManager().scheduleTransaction(clientTransaction);
    }
    
    //ClientLifecycleManager
    void scheduleTransaction(ClientTransaction transaction) {
        //这里获取到的就是 ApplicationThread 对象,在创建 Transaction 的时候也能看出,传入了 app.thread
        final IApplicationThread client = transation.getClient();
        //这里看似和 client 无关,其实进去之后就会发现,它只是包了一层,真正执行的是 client
        transaction.schedule();
        if(!(client instanceof Binder)) {
            transaction.recycle();
        }
    }
    
    //ApplicationThread
    public void scheduleTransaction(ClientTransaction transaction) {
        //ApplicationThread 也不处理,转交给了 ActivityThread
        //其实 ActivityThread 也没处理,这个方法是父类 ClientTransactionHandler 的
        ActivityThread.this.scheduleTransaction(transaction);
    }
    
    //ClientTransactionHandler
    void scheduleTransaction(ClientTransaction transaction) {
        //这个先不管,先看熟悉的发送消息
        transaction.preExecute(this);
        //这个还是会交给 ActivityThread 里的 mH 来处理
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
    
    //mH
    public void handleMessage(Message msg) {
        switch(msg.what) {
            case EXECUTE_TRANSACTION:
                //取出 transaction 交给事务处理器处理
                final ClientTransaction transaction = (ClientTransaction) msg.obj;
                mTransactionExecutor.execute(transaction);
                if(isSystem()) {
                    transaction.recycle();
                }
                break;
        }
    }
    

    到这我们知道从 ActivityStackSupervisor 真正要启动 Activity 开始,就一步步的创建了事务,并通过 Lifecycle 管理器来转发事务,并最终交给 ActivityThread 内部的 mTransactionExecutor 来执行事务。

    //TransactionExecutor
    public void execute(ClientTransaction transaction) {
        //逐步分析吧
        executeCallbacks(transaction);
        executeLifecycleState(transaction);
    }
    public void executeCallbacks(ClientTransaction transaction) {
        //这里来回顾下前面的 realStartActivityLocked,在 transaction 创建之后
        //添加了一个 LaunchActivityItem 对象 的 ClientTransactionItem
        //所以这里就能获取到
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
        final int size = callbacks.size();
        for(int i = 0; i < size; ++i) {
            final ClientTransactionItem item = callbacks.get(i);
            //这里会去执行具体的 callback,当前情况应该就是 LaunchActivityItem 对象
            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
        }
    }
    
    //LaunchActivityItem
    public void execute(ClienTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) {
        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIden, mInfo, mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState, mPendingResults, mPendingNewIntents, mIsForward, mProfilerInfo, client);
        //这里就有点熟悉了,看来没错就是这里了。
        //不过我们再回过头看看 client
        //client 的类定义不就是 ActivityThread 的父类么,所以这个有可能就是 ActivityThread 对象
        //经过对 ActivityThread 的成员变量 mTransactionExecutor 的分析确定了 client 就是 ActivityThread 对象
        //或者我们换个思路 handleLaunchActivity 在 ClienTransactionHandler 里是抽象方法,那必定由子类实现,而 ActivityThread 就是其子类
        client.handleLaunchActivity(r, pendingActions, null);
    }
    

    接下来就是做一些初始化准备,创建并启动 Activity

    //ActivityThread
    public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) {
        WindowManagerGlobal.initialize();
        final Activity a = performLaunchActivity(r, customIntent);
        return a;
    }
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            //这里创建出 Activity 对象实例,这个过程类似于 Application 对象实例的创建
            activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
        }
        
        try {
            //这里我是有疑问的,因为在启动应用进程时会调用 handleBindApplication 方法
            //在那个方法里也会创建 Application 对象实例,并且也会执行 onCreate
            //而这里也会创建并执行 onCreate,难道启动一个 Activity 就会执行一遍 Application 的方法?
            //这显然是不可能的
            //有一点不同的是,bindApplication 时 mInitialApplication 这个成员变量会被赋值
            //而这里仿佛会用于 activity 执行 attach 方法。
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
            if(activity != null) {
                Window window = null;
                if(r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                    window = r.mPendingRemoveWindow;
                }
                //做 attach 操作,这里传入的 appContext 就是 getBaseContext 方法返回的 mBase 对象
                activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config, r.referrer, r.voiceInteractor, window, r.configCallback);
                //执行 activity onCreate 方法
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
        }
        return activity;
    }
    

    对于代码中 Application 对象的创建我忽略了一个校验,就是在 makeApplication 方法中会判断成员变量 mApplication 是否已经存在,已存在就直接返回,这样就不会执行 onCreate 方法了。如果不存在就会创建并赋值给 mApplication 变量。

    这样看来,这里的 app 对象和 handleBindApplication 里的 app对象是同一个,这也就保证了一个应用对应一个 Application 对象,onCreate 方法也就只做一次了。

    参考文章
    ActvitityThread中的performLaunchActivity(ActivityClientRecord r, Intent customIntent)解析

    相关文章

      网友评论

        本文标题:根 Activity 的启动后续

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