Activity启动流程(四)从远端回到本地进程到activity的onPause(mClient.scheduleTransaction(this);)
发布日期:2021-07-23 22:22:28 浏览次数:1 分类:技术文章

本文共 13360 字,大约阅读时间需要 44 分钟。

一:从mClient.scheduleTransaction 到ApplicationThread

上文讲到

void scheduleTransaction(ClientTransaction transaction) throws RemoteException {        final IApplicationThread client = transaction.getClient();        transaction.schedule();        if (!(client instanceof Binder)) {            // If client is not an instance of Binder - it's a remote call and at this point it is            // safe to recycle the object. All objects used for local calls will be recycled after            // the transaction is executed on client in ActivityThread.            transaction.recycle();        }
public void schedule() throws RemoteException {        mClient.scheduleTransaction(this);    }

此处的mClient其实就是一个IApplicationThread的接口实现类,其实就是本地应用程序在远端的一个代理

其本地实体是

private class ApplicationThread extends IApplicationThread.Stub {        private static final String DB_INFO_FORMAT = "  %8s %8s %14s %14s  %s";        private int mLastProcessState = -1;

可以看到,这个类继承了IApplicationThread.Stub, 这个就是前面远端对应的本地类了

二从ApplicaitonThread到ActivityThread

看下ApplicationThread的scheduleTransaction方法

@Override        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {            ActivityThread.this.scheduleTransaction(transaction);        }

调用的是ActivityThread的方法,

这个方法ActivityThread类没有,在其父类中

继续看

// Schedule phase related logic and handlers.    /** Prepare and schedule transaction for execution. */    void scheduleTransaction(ClientTransaction transaction) {        transaction.preExecute(this);        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);    }

sendMessage是个抽象方法,这个方法的实现在ActivityThread类中

private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {        if (DEBUG_MESSAGES) Slog.v(            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)            + ": " + arg1 + " / " + obj);        Message msg = Message.obtain();        msg.what = what;        msg.obj = obj;        msg.arg1 = arg1;        msg.arg2 = arg2;        if (async) {            msg.setAsynchronous(true);        }        mH.sendMessage(msg);    }

看下这个H类

class H extends Handler {        public static final int BIND_APPLICATION        = 110;        public static final int EXIT_APPLICATION        = 111;        public static final int RECEIVER                = 113;        public static final int CREATE_SERVICE          = 114;        public static final int SERVICE_ARGS            = 115;        public static final int STOP_SERVICE            = 116;

这个message最后在这里处理

case EXECUTE_TRANSACTION:                    final ClientTransaction transaction = (ClientTransaction) msg.obj;                    mTransactionExecutor.execute(transaction);                    if (isSystem()) {                        // Client transactions inside system process are recycled on the client side                        // instead of ClientLifecycleManager to avoid being cleared before this                        // message is handled.                        transaction.recycle();                    }                    // TODO(lifecycler): Recycle locally scheduled transactions.                    break;

三 从ActivityThread 到TransactionExecutor

上文中在case EXECUTE_TRANSACTION中做了mTransactionExecutor.execute 操作,我们点进去看看

/**     * Resolve transaction.     * First all callbacks will be executed in the order they appear in the list. If a callback     * requires a certain pre- or post-execution state, the client will be transitioned accordingly.     * Then the client will cycle to the final lifecycle state if provided. Otherwise, it will     * either remain in the initial state, or last state needed by a callback.     */    public void execute(ClientTransaction transaction) {        final IBinder token = transaction.getActivityToken();        log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);        executeCallbacks(transaction);        executeLifecycleState(transaction);        mPendingActions.clear();        log("End resolving transaction");    }
/** Cycle through all states requested by callbacks and execute them at proper times. */    @VisibleForTesting    public void executeCallbacks(ClientTransaction transaction) {        final List
callbacks = transaction.getCallbacks(); if (callbacks == null) { // No callbacks to execute, return early. return; } log("Resolving callbacks"); final IBinder token = transaction.getActivityToken(); ActivityClientRecord r = mTransactionHandler.getActivityClient(token); // In case when post-execution state of the last callback matches the final state requested // for the activity in this transaction, we won't do the last transition here and do it when // moving to final state instead (because it may contain additional parameters from server). final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest(); final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState() : UNDEFINED; // Index of the last callback that requests some post-execution state. final int lastCallbackRequestingState = lastCallbackRequestingState(transaction); final int size = callbacks.size(); for (int i = 0; i < size; ++i) { final ClientTransactionItem item = callbacks.get(i); log("Resolving callback: " + item); final int postExecutionState = item.getPostExecutionState(); final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r, item.getPostExecutionState()); if (closestPreExecutionState != UNDEFINED) { cycleToPath(r, closestPreExecutionState); } item.execute(mTransactionHandler, token, mPendingActions); item.postExecute(mTransactionHandler, token, mPendingActions); if (r == null) { // Launch activity request will create an activity record. r = mTransactionHandler.getActivityClient(token); } if (postExecutionState != UNDEFINED && r != null) { // Skip the very last transition and perform it by explicit state request instead. final boolean shouldExcludeLastTransition = i == lastCallbackRequestingState && finalState == postExecutionState; cycleToPath(r, postExecutionState, shouldExcludeLastTransition); } } } /** Transition to the final state if requested by the transaction. */ private void executeLifecycleState(ClientTransaction transaction) { final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest(); if (lifecycleItem == null) { // No lifecycle request, return early. return; } log("Resolving lifecycle state: " + lifecycleItem); final IBinder token = transaction.getActivityToken(); final ActivityClientRecord r = mTransactionHandler.getActivityClient(token); if (r == null) { // Ignore requests for non-existent client records for now. return; } // Cycle to the state right before the final requested state. cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */); // Execute the final transition with proper parameters. lifecycleItem.execute(mTransactionHandler, token, mPendingActions); lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions); }

四 从TransactionExecutor到ActivityLifecycleItem

我们看下lifecycleItem.execute方法

这个其实是个抽象方法

/**     * Execute the request.     * @param client Target client handler.     * @param token Target activity token.     * @param pendingActions Container that may have data pending to be used.     */    void execute(ClientTransactionHandler client, IBinder token,            PendingTransactionActions pendingActions);

对于当前情景下,其实是PauseActivityItem.execute 这个方法

看下具体代码

@Override    public void execute(ClientTransactionHandler client, IBinder token,            PendingTransactionActions pendingActions) {        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");        client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,                "PAUSE_ACTIVITY_ITEM");        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);    }

五:从ActivitLifeCycleItem到ActivityThread

这里的handlePauseActivity其实又回到了ActivityThread

看下activity的handlePauseActivity方法

@Override    public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,            int configChanges, PendingTransactionActions pendingActions, String reason) {        ActivityClientRecord r = mActivities.get(token);        if (r != null) {            if (userLeaving) {                performUserLeavingActivity(r);            }            r.activity.mConfigChangeFlags |= configChanges;            performPauseActivity(r, finished, reason, pendingActions);            // Make sure any pending writes are now committed.            if (r.isPreHoneycomb()) {                QueuedWork.waitToFinish();            }            mSomeActivitiesChanged = true;        }    }

这里的关键方法是 performPauseActivity 方法

/**     * Pause the activity.     * @return Saved instance state for pre-Honeycomb apps if it was saved, {@code null} otherwise.     */    private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason,            PendingTransactionActions pendingActions) {        if (r.paused) {            if (r.activity.mFinished) {                // If we are finishing, we won't call onResume() in certain cases.                // So here we likewise don't want to call onPause() if the activity                // isn't resumed.                return null;            }            RuntimeException e = new RuntimeException(                    "Performing pause of activity that is not resumed: "                    + r.intent.getComponent().toShortString());            Slog.e(TAG, e.getMessage(), e);        }        if (finished) {            r.activity.mFinished = true;        }        // Pre-Honeycomb apps always save their state before pausing        final boolean shouldSaveState = !r.activity.mFinished && r.isPreHoneycomb();        if (shouldSaveState) {            callActivityOnSaveInstanceState(r);        }        performPauseActivityIfNeeded(r, reason);        // Notify any outstanding on paused listeners        ArrayList
listeners; synchronized (mOnPauseListeners) { listeners = mOnPauseListeners.remove(r.activity); } int size = (listeners != null ? listeners.size() : 0); for (int i = 0; i < size; i++) { listeners.get(i).onPaused(r.activity); } final Bundle oldState = pendingActions != null ? pendingActions.getOldState() : null; if (oldState != null) { // We need to keep around the original state, in case we need to be created again. // But we only do this for pre-Honeycomb apps, which always save their state when // pausing, so we can not have them save their state when restarting from a paused // state. For HC and later, we want to (and can) let the state be saved as the // normal part of stopping the activity. if (r.isPreHoneycomb()) { r.state = oldState; } } return shouldSaveState ? r.state : null; }

继续 performPauseActivityIfNeeded

private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {        if (r.paused) {            // You are already paused silly...            return;        }        try {            r.activity.mCalled = false;            mInstrumentation.callActivityOnPause(r.activity);            if (!r.activity.mCalled) {                throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)                        + " did not call through to super.onPause()");            }        } catch (SuperNotCalledException e) {            throw e;        } catch (Exception e) {            if (!mInstrumentation.onException(r.activity, e)) {                throw new RuntimeException("Unable to pause activity "                        + safeToComponentShortString(r.intent) + ": " + e.toString(), e);            }        }        r.setState(ON_PAUSE);    }

六:从ActivityThread到Instrumentation

到这里终于又见到了熟悉的Instrumentaition,点进去

/**     * Perform calling of an activity's {@link Activity#onPause} method.  The     * default implementation simply calls through to that method.     *      * @param activity The activity being paused.     */    public void callActivityOnPause(Activity activity) {        activity.performPause();    }

七 进入activity

final void performPause() {        mDoReportFullyDrawn = false;        mFragments.dispatchPause();        mCalled = false;        onPause();        writeEventLog(LOG_AM_ON_PAUSE_CALLED, "performPause");        mResumed = false;        if (!mCalled && getApplicationInfo().targetSdkVersion                >= android.os.Build.VERSION_CODES.GINGERBREAD) {            throw new SuperNotCalledException(                    "Activity " + mComponent.toShortString() +                    " did not call through to super.onPause()");        }    }

至此,activity的pause方法终于走完了。。

转载地址:https://blog.csdn.net/perfectnihil/article/details/91042432 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Activity启动流程(五)Activity所在进程启动过程及ActivityThread初始化
下一篇:Activity启动流程(三)从远端回到本地进程(mClient.scheduleTransaction(this);)

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年02月28日 14时55分47秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

php rewrite url_PHP_URL Rewrite的设置方法,URL Rewrite需要服务器的支持! - phpStudy 2019-04-21
php读取大文件某行内容,PHP读取和修改大文件的某行内容_PHP教程 2019-04-21
打印php错误日志,php怎样打印错误日志 2019-04-21
Calendar导入java,Java程序使用Calendar.add()方法将分钟添加到当前时间 2019-04-21
mysql中用户线程作用,mysql用户线程的建立与用户线程的状态源码解析 2019-04-21
php页面引用公共文件,WeiPHP插件模板中快速引入公共模板文件 2019-04-21
php tracy,admin.php 2019-04-21
php访问父类的所有属性,php – 在父类中使用$this仅在子类中显示父类属性 2019-04-21
oracle比较强大的函数,SQL和ORACLE函数比较 2019-04-21
oracle12c order by,oracle 数据库中order by 的一些高级用法 2019-04-21
oracle8i substr,Oracle中的INSTR,NVL和SUBSTR函数的用法详解 2019-04-21
导出oracle11g的空表,轻松解决oracle11g 空表不能 exp 导出 的问题。 2019-04-21
php把整数拆分成数组,数组拆分处理(整数时的处理),该怎么处理 2019-04-21
oracle numlist,oracle sql str2numlist numtabletype 2019-04-21
php红包平均分配,红包平均分配算法 2019-04-21
linux磁盘的命令是,linux磁盘相关的命令 2019-04-21
linux 停用用户,linux – 如何禁用用户的网络访问? 2019-04-21
linux服务器 缓存,Linux服务器内存使用分析及内存缓存 2019-04-21
linux查进程内存问题,关于linux 查看服务进程内存,cpu,内存占用的一些基础命令... 2019-04-21
linux英文包安装教程视频,Linux源码包安装过程讲解 2019-04-21