Android ActivityManagerService总结(四)startActivity流程

一.前言

         AMS(ActivityManagerService)是Activity管理的核心组件,提供了Activity的启动、生命周期管理、栈管理等功能,熟悉AMS会对我们认识Activity的工作原理有很大的帮助.

        AMS中内容实在是太多了,对它的分析也不可能面面俱到,从Activity的启动、Activity消息回传(onActivityResult)、Activity栈管理、AMS与WMS和PMS的协同工作这几个点深入理解一下,通过对源码的流程梳理, 对AMS有进一步的理解.

        阅读本篇文章之前,请务必阅读笔者应用层中startActivity的生命周期这片文章,  我们针对文中提到的3个问题,然后在Framework层中去寻找答案, 本文是用Android11源码跟踪的流程

1. 当在同一个进程中调用startActivity方法的流程是怎么样的?

2. 当启动另外一个进程中的Activity时, startActivity的调用流程又是什么样的?

3. 启动一个新的Activity, 为什么先是执行onPause方法,然后待新界面显示完成后,在执行onStop方法?
 

二. AMS协作类

先了解一下历史版本的变更情况

在Android 10 中安卓为了将来的方案更设计更加明确,对AMS做了很多修改,安卓的最终目的是把activity 和window融合

Android 10中引入了ActivityTaskManagerService(ATMS)的概念

Android 9.0 及以前版本,Acitivity 管理由AMS 和WMS 协作完成,导致在AMS 和WMS 中都有相似功能的实体,除了大量的代码冗余之外,二者之间的协作也非常困难。

从Android 10.0 的代码变更看,google 最终的目的是把activity和window融合

把AMS 下面只和activity 管理相关的代码移到WMS的目录下,actvityStack、activityRecord 等文件,全部移到WMS 目录下,和window 统一管理. AMS中部分文件拆分,把原来activity和其他组件融合在一起处理的文件进行拆分,activity 相关部分单独拆分,移到WMS 中统一
管理。


比如ActivityManagerService.java 拆分成了ActivityManagerService.java 和 ActivityTaskManagerService.java 两个文件,


activity 的启动由ActivityTaskManagerService.java 负责
因为Activity 和window的管理统一由WMS 完成,不再需要之前的DispayWindowController、stackWindowController 来居中协调,可以把display、stack、task 等统一管理。最终要做到完全融合,以stack 为例,完成后会把taskstack的功能完全融合进activityStack,目前只做到了在activityStack 中包含taskstack。创建、管理流程也随之发生变化。

几个关键类介绍

类名 功能描述
Instrumentation 负责调用Activity和Application生命周期
ActivityTaskManagerService 负责Activity管理和调度等工作, ATMS是Android10中新增内容
ActivityManagerService 负责管理四大组件和进程,包括生命周期和状态切换。
ActivityTaskManagerInternal 是由ActivityTaskManagerService对外提供的一个抽象类,真正
的实现是在 ActivityTaskManagerService#LocalService
ActivityThread 管理应用程序进程中主线程的执行
ActivityStackSupervisor 负责所有Activity栈的管理
TransactionExecutor 主要作用是执行ClientTransaction
ClientLifecycleManager 生命周期的管理调用

三. 同一进程中startActivity流程

起点代码

 Intent intent = new Intent(MainActivity.this, SecondActivity.class);
 //调用Activity.java中的startActivity方法
 startActivity(intent);

因为细节太多,我只把最关键核心的时序图画出来

                                                                   图一 startActivity时序图

我们来看第3个问题 启动一个新的Activity, 为什么先是执行onPause方法?

对应的源码流程在

frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java的resumeTopActivityInnerLocked方法中  上面时序图第12步

 @GuardedBy("mService")
    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {

     if (!mService.isBooting() && !mService.isBooted()) {
            // Not ready yet!
            return false;
     }
     .....
     // Activity栈中有需要Pause操作的Activity
     boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
     if (mResumedActivity != null) {
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
            // 暂停当前正在显示的Activity
            pausing |= startPausingLocked(userLeaving, false, next, false);
     }
.....
}

再继续看看startPausingLocked方法

 final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
            ActivityRecord resuming, boolean pauseImmediately) {

.....
    if (prev.attachedToProcess()) {
            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
            try {
                EventLogTags.writeAmPauseActivity(prev.mUserId, System.identityHashCode(prev),
                        prev.shortComponentName, "userLeaving=" + userLeaving);

           //关键代码, 这里是执行Activity onPause的方法   
             mService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
                        prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
                                prev.configChangeFlags, pauseImmediately));
                mService.notifyActivityStateChange(prev.intent, ProcessInfo.ACTIVITY_STATE_PAUSE, null);
            } catch (Exception e) {
                // Ignore exception, if process died other code will cleanup.
                Slog.w(TAG, "Exception thrown during pause", e);
                mPausingActivity = null;
                mLastPausedActivity = null;
                mLastNoHistoryActivity = null;
            }
.....
}

到这里 MainActivity的 onPause方法就执行完后, 就开始 SecondActivity的 onCreate  onStart onResume 回调方法

对应上图的第14个步骤

/frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java

#startSpecificActivityLocked方法

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 {
                //如果是同一进程的话,就直接启动目标Activity
                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;
        }

        // Suppress transition until the new activity becomes ready, otherwise the keyguard can
        // appear for a short amount of time before the new process with the new activity had the
        // ability to set its showWhenLocked flags.
        if (getKeyguardController().isKeyguardLocked()) {
            r.notifyUnknownVisibilityLaunched();
        }

        try {
            if (Trace.isTagEnabled(TRACE_TAG_ACTIVITY_MANAGER)) {
                Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dispatchingStartProcess:"
                        + r.processName);
            }
            // Post message to start process to avoid possible deadlock of calling into AMS with the
            // ATMS lock held.
            //如果不是同进程,且进程没有启动, 则需要去fork一个新进程.
            final Message msg = PooledLambda.obtainMessage(
                    ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
                    r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
            mService.mH.sendMessage(msg);
        } finally {
            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
        }
    }

如果是同一进程,就直接调用realStartActivityLocked 方法

如果不是同一进程,且进程还未启动, 就调用ActivityManagerInternal::startProcess 去fork一个新的进程.

接下来,继续分析realStartActivityLocked里面的方法

 boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {
.....
     //关键代码
  // Create activity launch transaction.
                final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.appToken);


 clientTransaction.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));

                // Set desired final state.
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
                clientTransaction.setLifecycleStateRequest(lifecycleItem);

                // Schedule transaction.
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);


......

}

封装好一个 ClientTransaction 对象,然后供TransactionExecutor.java 中execute()方法执行

clientTransaction.addCallback(封装的是一个 LaunchActivityItem 对象), 也就是需要启动的Activity对象

最后由这句代码mService.getLifecycleManager().scheduleTransaction(clientTransaction)安排执行,   这句代码就跳转到

frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java

的scheduleTransaction方法

 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();
        }
    }

调用realStartActivityLocked之后的时序图如下:

到第13步骤的时候, 执行 performLaunchActivity方法, SecondActivity就创建并回调onCreate方法

四. 不同进程中startActivity流程

起始代码:

 startBprocessBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent();
                ComponentName componentName = new ComponentName("com.example.myclient",
                        "com.example.myclient.BprocessActivity");
                intent.setComponent(componentName);
                try{
                    startActivity(intent);
                } catch (Exception e) {
                    Log.e("activity", "error:  "+e.getMessage());
                }
            }
        });

接第二小结继续分析,如果不是同一进程, 那么会走startProcess的代码流程

关于新启动一个进程,笔者之前也分析对应的流程,请查阅Android 进程间通信机制(四) 应用进程启动过程

待进程创建成功并启动后, 在来分析一下如何走到BprocessActivity 的onCreate 方法?

应用进程创建成功后,  首先执行的ActivityThread.java 的main方法, 流程图如下:

接上一张图 

 

 好了,图中的最后一步 mStackSupervisor.attachApplicationLocked(app) 接下来调用到mStackSupervisor.realStartActivityLocked 的方法中

也就是第三节中realStartActivityLocked之后的流程, 流程是一样的,走完之后,那么 BprocessActivity就被创建成功并回调生命周期的onCreate方法.

五. 待更新

猜你喜欢

转载自blog.csdn.net/u012514113/article/details/129930436