android activity启动流程_Android 源码分析——Activity启动流程

前言

前面一篇文章中我们介绍了 Application 的创建,我们这里简单回顾一下,主要有下面几个类及方法:

  • ActivityThread

    • main

    • attach

  • ActivityManagerService

    • attachapplicationLocked

  • ActivityThread.ApplicationThread

    • bindApplication

    • handleBindApplication

  • Instrumentation

    • onCreate

    • callApplicationOnCreate

我们前面提到在 AMS 中的 attachApplicationLocked 方法中调用了 bindApplication之后才逐步创建了 Application,我们今天就接着前一篇文章,从 bindApplication 之后继续往下看:

一、AMS.attachApplicationLocked

 1    @GuardedBy("this")
2    private final boolean attachApplicationLocked(IApplicationThread thread,
3            int pid, int callingUid, long startSeq) {
4        /************************省略部分代码********************************/
5           final ActiveInstrumentation instr2 = app.getActiveInstrumentation();
6            if (app.isolatedEntryPoint != null) {
7                // This is an isolated process which should just call an entry point instead of
8                // being bound to an application.
9                thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
10            } else if (instr2 != null) {
11                thread.bindApplication(processName, appInfo, providers,
12                        instr2.mClass,
13                        profilerInfo, instr2.mArguments,
14                        instr2.mWatcher,
15                        instr2.mUiAutomationConnection, testMode,
16                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
17                        isRestrictedBackupMode || !normalMode, app.isPersistent(),
18                        new Configuration(app.getWindowProcessController().getConfiguration()),
19                        app.compat, getCommonServicesLocked(app.isolated),
20                        mCoreSettingsObserver.getCoreSettingsLocked(),
21                        buildSerial, autofillOptions, contentCaptureOptions);
22            } else {
23                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
24                        null, null, null, testMode,
25                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
26                        isRestrictedBackupMode || !normalMode, app.isPersistent(),
27                        new Configuration(app.getWindowProcessController().getConfiguration()),
28                        app.compat, getCommonServicesLocked(app.isolated),
29                        mCoreSettingsObserver.getCoreSettingsLocked(),
30                        buildSerial, autofillOptions, contentCaptureOptions);
31            }
32       /************************省略部分代码********************************/
33        if (normalMode) {
34            try {
35                didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
36            } catch (Exception e) {
37                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
38                badApp = true;
39            }
40        }
41        /************************省略部分代码********************************/
42    }

我们会看到在这后面执行了这个mAtmInternal.attachApplication(app.getWindowProcessController())方法,我们看源码发现mAtmInternal 是一个ActivityTaskManagerInternal对象,但是ActivityTaskManagerInternal是一个抽象类,具体实现逻辑实在ActivityTaskManagerService.LocalService.

这里是Android 10 中的最大的重构之处,Google 工程师将 AMS 中的部分功能分给了 ATMS(也就是ActivityTaskManagerService)。ATMS 是 Android 10 中新引入的类。主要是负责接管 Activity 生命周期相关的接口。同时 ATMS 也对外提供了一个抽象类 ActivityTaskManagerInternal。它的具体实现实在 ActivityTaskManagerService.LocalService。
那么我们接下来就看看 ATMS 中 LocalService.attachApplication 的源码:

二、ATMS.LocalService.attachApplication

1    @HotPath(caller = HotPath.PROCESS_CHANGE)
2    @Override
3    public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
4        synchronized (mGlobalLockWithoutBoost) {
5            return mRootActivityContainer.attachApplication(wpc);
6        }
7    }

这里我们看到它又调用了 RootActivityContainer 中的 attachApplication.

RootActivityContainer 也是 Android 10 中新引入的类,这个类是临时的,用于将ActivityStackSupervisor.java中的内容分离出来。这个
目的是将其与RootWindowContainer.java合并,作为统一层次结构的一部分。

三、RootActivityContainer.attachApplication

 1   boolean attachApplication(WindowProcessController app) throws RemoteException {
2        final String processName = app.mName;
3        boolean didSomething = false;
4        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
5            final ActivityDisplay display = mActivityDisplays.get(displayNdx);
6            final ActivityStack stack = display.getFocusedStack();
7            if (stack != null) {
8                stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
9                final ActivityRecord top = stack.topRunningActivityLocked();
10                final int size = mTmpActivityList.size();
11                for (int i = 0; i 12                    final ActivityRecord activity = mTmpActivityList.get(i);
13                    if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
14                            && processName.equals(activity.processName)) {
15                        try {
16                            //TODO 这一大段的核心代码就这一句
17                            if (mStackSupervisor.realStartActivityLocked(activity, app,
18                                    top == activity /* andResume */, true /* checkConfig */)) {
19                                didSomething = true;
20                            }
21                        } catch (RemoteException e) {
22                            Slog.w(TAG, "Exception in new application when starting activity "
23                                    + top.intent.getComponent().flattenToShortString(), e);
24                            throw e;
25                        }
26                    }
27                }
28            }
29        }
30        if (!didSomething) {
31            ensureActivitiesVisible(null, 0, false /* preserve_windows */);
32        }
33        return didSomething;
34    }

这里的一大段核心代码就一句:ActivityStackSupervisor.realStartActivityLocked(activity, app,top == activity , true)
那我们还是继续往下看,看看 StackSupervisor.realStartActivityLocked

四、ActivityStackSupervisor.realStartActivityLocked

 1    boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
2            boolean andResume, boolean checkConfig) throws RemoteException {
3            /************************省略部分代码********************************/
4                // TODO 注释 1 创建 Activity 的消息容器
5                final ClientTransaction clientTransaction = ClientTransaction.obtain(
6                        proc.getThread(), r.appToken);
7
8                final DisplayContent dc = r.getDisplay().mDisplayContent;
9                //TODO 注释 2 这里加入了LaunchActivityItem 也就是将Activity启动事务加入到消息容器
10                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
11                        System.identityHashCode(r), r.info,
12                        // TODO: Have this take the merged configuration instead of separate global
13                        // and override configs.
14                        mergedConfiguration.getGlobalConfiguration(),
15                        mergedConfiguration.getOverrideConfiguration(), r.compat,
16                        r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
17                        r.icicle, r.persistentState, results, newIntents,
18                        dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
19                                r.assistToken));
20
21                // Set desired final state.
22                final ActivityLifecycleItem lifecycleItem;
23                if (andResume) {
24                    lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
25                } else {
26                    lifecycleItem = PauseActivityItem.obtain();
27                }
28                //TODO 注释 3 这里加入了 ResumeActivityItem/PauseActivityItem 
29                clientTransaction.setLifecycleStateRequest(lifecycleItem);
30
31                //TODO 注释 4 mService 是 ATMS 对象。ClientLifecycleManager处理前面加入的一系列消息
32                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
33
34                 /************************省略部分代码********************************/
35        // Perform OOM scoring after the activity state is set, so the process can be updated with
36        // the latest state.
37        proc.onStartActivity(mService.mTopProcessState, r.info);
38        /************************省略部分代码********************************/
39        return true;
40    }

这里我们依旧还是只看核心的代码,我们看到这里它创建了一个ClientTransaction,然后添加了一些LaunchActivityItem,ResumeActivityItem等。这里我们看四处注释:

  1. 创建一个 ClientTransaction 对象:

  2. 向之前创建的 ClientTransaction 对象中加入 Activity 启动消息【LaunchActivityItem】。

  3. 向之前创建的 ClientTransaction 对象设置生命周期的状态【ResumeActivityItem/PauseActivityItem】 。

  4. 获取 ATMS 中的 ClientLifecycleManager 管理前面 ClientTransaction 对象中加入的一系列消息。
    上面我们看到注释 2 调用了ClientTransaction.addCallback这个方法,下面我们就来看看

1.ClientTransaction.addCallback

ClientTransaction 这个类是一个包含一系列消息的容器,这些消息可以被发送到客户端。这消息可以是一个回调也可以是一个Activity的生命周期状态。

1    private List mActivityCallbacks;2    public void addCallback(ClientTransactionItem activityCallback) {3        if (mActivityCallbacks == null) {4            mActivityCallbacks = new ArrayList<>();5        }6        mActivityCallbacks.add(activityCallback);7    }

这个方法我们看到非常简单就是在 mActivityCallbacks(回调/消息列表)的队尾增加了一个 ClientTransactionItem (消息/回调)实例。

2.ATMS.getLifecycleManager()

注释 4 处的 mService 是一个 ATMS 对象。所以这里的 getLifecycleManager 是 ATMS 中的getLifecycleManager

1   ClientLifecycleManager getLifecycleManager() {
2        return mLifecycleManager;
3    }

我们看到直接返回了一个 ClientLifecycleManager ,所以最终注释 4 执行的是 ClientLifecycleManager.scheduleTransaction 下面我们看看这个类:

3.ClientLifecycleManager.scheduleTransaction

ClientLifecycleManager 这个类就是专门来管理前面ClientTransaction 消息容器中的一系列消息的,下面我们看看它的scheduleTransaction

1 void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
2        final IApplicationThread client = transaction.getClient();
3        transaction.schedule();
4        if (!(client instanceof Binder)) {
5            transaction.recycle();
6        }
7    }

Emmm………走了一圈又走回来了,最终还是调用 ClientTransaction 它自己的方法去执行。可能这里很多小伙伴会想:那之前 ClientLifecycleManager 这个类是干啥的?这个类是用来管理
Activity 生命周期相关的消息/回调,而消息/回调的处理还是在 ClientTransaction 自己。

4.ClientTransaction.schedule()

 1   /** 2     * Schedule the transaction after it was initialized. It will be send to client and all its 3     * individual parts will be applied in the following sequence: 4     * 1. The client calls {@link #preExecute(ClientTransactionHandler)}, which triggers all work 5     *    that needs to be done before actually scheduling the transaction for callbacks and 6     *    lifecycle state request. 7     * 2. The transaction message is scheduled. 8     * 3. The client calls {@link TransactionExecutor#execute(ClientTransaction)}, which executes 9     *    all callbacks and necessary lifecycle transitions.10     */
11    public void schedule() throws RemoteException {
12        mClient.scheduleTransaction(this);
13    }

这个方法是所有消息/回调的处理,我们看看它的注释:
这个方法在 transaction 初始化完成后执行,它将会发送给客户端。并且它的所有的单独的都按照以下方法执行:

客户端调用 ClientTransactionHandler.preExecute 这将触发在为回调和生命周期状态请求实际调度任务之前的所有操作。

transaction 中的消息被调度。

客户端调用 TransactionExecutor.execute 执行所有回调和必要的生命周期转换。

我们继续追踪 ApplicationThread.scheduleTransaction(this)

5.ApplicationThread.scheduleTransaction

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

这里我们看到它有调用了 ActivityThread.this.scheduleTransaction(transaction) ,我们没有在 ActivityThread 中找到 scheduleTransaction,那么它就去执行了父类的 scheduleTransaction。我们找到 ActivityThread 的父类 ClientTransactionHandler.

6.ClientTransactionHandler.scheduleTransaction

1    void scheduleTransaction(ClientTransaction transaction) {
2        transaction.preExecute(this);
3        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
4    }

这里我看到调用了前面注释中的第一条和第二条。

  1. transaction.preExecute(this): 执行实际调度任务之前的所有准备操作。

  2. sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction): 发送消息调度任务,消息的处理还是在 ActivityThread.H.handleMessage

7.ActivityThread.H.handleMessage

1   case EXECUTE_TRANSACTION:
2        final ClientTransaction transaction = (ClientTransaction) msg.obj;
3        mTransactionExecutor.execute(transaction);
4        if (isSystem()) {
5           transaction.recycle();
6        }
7        break;

这里我们看到了它执行了前面注释的第三条:mTransactionExecutor.execute(transaction): 客户端调用 TransactionExecutor.execute 执行所有回调和必要的生命周期转换。

五、TransactionExecutor.execute

1 public void execute(ClientTransaction transaction) {
2     /************************省略部分代码********************************/
3        //处理所有的回调/消息,按照顺序执行,先执行 LaunchActivityItem
4        executeCallbacks(transaction);
5        //处理必要的生命周期转换,ResumeActivityItem/PauseActivityItem
6        executeLifecycleState(transaction);
7        mPendingActions.clear();
8    }

这个方法就是处理之前的任务:

  1. executeCallbacks(transaction): 首先,按照消息/回调列表中的消息/回调挨个执行。

  2. executeLifecycleState(transaction) 然后进行必要的生命周期转换。

1. TransactionExecutor.executeCallbacks

 1public void executeCallbacks(ClientTransaction transaction) {
2        //TODO 拿到消息/回调列表
3        final List callbacks = transaction.getCallbacks(); 4         /************************省略部分代码********************************/ 5        final int size = callbacks.size(); 6        for (int i = 0; i  7             //TODO 拿到具体的消息/回调 8            final ClientTransactionItem item = callbacks.get(i); 9            //TODO 执行任务10            item.execute(mTransactionHandler, token, mPendingActions);11            item.postExecute(mTransactionHandler, token, mPendingActions);1213            if (r == null) {14                // Activity 创建后将创建一个 Activity 活动记录15                r = mTransactionHandler.getActivityClient(token);16            }17            /************************省略部分代码********************************/18        }19    }

这个方法主要是先拿到 ClientTransaction 中的消息/回调列表,执行具体的消息/回调。前面我们先加入了 LaunchActivityItem 那么下面就执行 LaunchActivityItem.execute

1.1 LaunchActivityItem.execute
 1    @Override
2    public void execute(ClientTransactionHandler client, IBinder token, 3            PendingTransactionActions pendingActions) {
4        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
5        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
6                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
7                mPendingResults, mPendingNewIntents, mIsForward,
8                mProfilerInfo, client, mAssistToken);
9        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
10        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
11    }

这个方法中我们只关注 client.handleLaunchActivity(r, pendingActions, null /* customIntent */);这个方法就是调用 ActivityThread.handleLaunchActivity.我们回到 ActivityThread 再看看

1.2 ActivityThread.handleLaunchActivity
 1 @Override
2    public Activity handleLaunchActivity(ActivityClientRecord r,
3            PendingTransactionActions pendingActions, Intent customIntent) {
4        /************************省略部分代码********************************/
5        handleConfigurationChanged(null, null);
6
7        if (localLOGV) Slog.v(
8            TAG, "Handling launch of " + r);
9
10        // Initialize before creating the activity
11        if (!ThreadedRenderer.sRendererDisabled
12                && (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
13            HardwareRenderer.preload();
14        }
15        // 初始化WindowManagerGlobal
16        WindowManagerGlobal.initialize();
17
18        // Hint the GraphicsEnvironment that an activity is launching on the process.
19        GraphicsEnvironment.hintActivityLaunch();
20         // 创建并启动Activity
21        final Activity a = performLaunchActivity(r, customIntent);
22       /************************省略部分代码********************************/
23
24        return a;
25    }

这个方法中的核心代码是:

  1. WindowManagerGlobal.initialize(): 初始化WindowManagerGlobal

  2. performLaunchActivity(r, customIntent):创建并启动Activity

1.3 ActivityThread.performLaunchActivity
 1   private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
2      /************************省略部分代码********************************/   
3    Activity activity = null;
4        try {
5            java.lang.ClassLoader cl = appContext.getClassLoader();
6            //创建 Activity
7            activity = mInstrumentation.newActivity(
8                    cl, component.getClassName(), r.intent);
9
10       /************************省略部分代码********************************/   
11            if (activity != null) {
12                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
13                Configuration config = new Configuration(mCompatConfiguration);
14                if (r.overrideConfig != null) {
15                    config.updateFrom(r.overrideConfig);
16                }
17
18                Window window = null;
19                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
20                    window = r.mPendingRemoveWindow;
21                    r.mPendingRemoveWindow = null;
22                    r.mPendingRemoveWindowManager = null;
23                }
24                appContext.setOuterContext(activity);
25                //创建 Activity 的 ContextImpl
26                activity.attach(appContext, this, getInstrumentation(), r.token,
27                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
28                        r.embeddedID, r.lastNonConfigurationInstances, config,
29                        r.referrer, r.voiceInteractor, window, r.configCallback,
30                        r.assistToken);
31
32                if (customIntent != null) {
33                    activity.mIntent = customIntent;
34                }
35                r.lastNonConfigurationInstances = null;
36                checkAndBlockForNetworkAccess();
37                activity.mStartedActivity = false;
38                int theme = r.activityInfo.getThemeResource();
39                if (theme != 0) {
40                //设置主题
41                    activity.setTheme(theme);
42                }
43
44                activity.mCalled = false;
45                // 通过 Instrumentation 调用 Activity 的 onCreate
46                if (r.isPersistable()) {
47                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
48                } else {
49                    mInstrumentation.callActivityOnCreate(activity, r.state);
50                }
51                if (!activity.mCalled) {
52                    throw new SuperNotCalledException(
53                        "Activity " + r.intent.getComponent().toShortString() +
54                        " did not call through to super.onCreate()");
55                }
56                r.activity = activity;
57            }
58            r.setState(ON_CREATE);
59            synchronized (mResourcesManager) {
60                mActivities.put(r.token, r);
61            }
62
63        } catch (SuperNotCalledException e) {
64            throw e;
65
66        } catch (Exception e) {
67            if (!mInstrumentation.onException(activity, e)) {
68                throw new RuntimeException(
69                    "Unable to start activity " + component
70                    + ": " + e.toString(), e);
71            }
72        }
73
74        return activity;
75    }

这个方法中主要做了:

  1. 通过 Instrumentation.newActivity 方法创建一个 Activity 对象

  2. 通过 Activity.attach 为 Activity 创建 ContextImpl。

  3. 通过 activity.setTheme(theme); 设置 Activity 的主题.

  4. 通过 Instrumentation.callActivityOnCreate 调用 Activity 的 onCreate。

走到这里算是 Activity 的就已经创建成功了,下面就是该执行 Activity 的别的生命周期了

2. TransactionExecutor.executeLifecycleState

1   private void executeLifecycleState(ClientTransaction transaction) {
2        // 获取 Activity 的最终状态 ResumeActivityItem/PauseActivityItem
3        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
4        // 执行 ResumeActivityItem/PauseActivityItem
5        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
6        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
7    }

这里拿到我们之前设置的 Activity 的状态[ResumeActivityItem/PauseActivityItem],然后执行:我们看看ResumeActivityItem

2.1 ResumeActivityItem.execute
1   @Override
2    public void execute(ClientTransactionHandler client, IBinder token,3            PendingTransactionActions pendingActions) {
4        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
5        client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
6                "RESUME_ACTIVITY");
7        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
8    }

这里跟 LauchActivityItem 一样,最终调用到了 ActivityThread,我们继续追踪会发现它紧接着调用了:

ActivityThread.performResumeActivity->Activity.performResume->Activity.performStart->Activity.onStart->Activity.onResume.

关于后面这些方法,读者可以自己追踪,这里就不多做说明了。

六、总结

说到这里关于 APP 从启动到到第一个启动的 Activity 就已经展示在用户界面上了。

db38218feb11ecf4b5376ab955d34bb6.png

Application 的创建流程

35c9db63bf1c4642f971d1e8eb7c79cf.png

View的事件分发机制从dispatchTouchEvent说起

e1cfb3212aa022e163f7f93c3cb910dc.png

View是如何被添加到手机屏幕的?

abe53d03c10e7fc41a133429674a8617.png

Android 热修复 AndFix 原理,看这篇就够了

44e63339df35c5150a33b9616f094762.png

App 黑白化实现探索2, 发现了一种更方便的方案,我被锤了!

327293ace1c1beafd70a90a6824a8ec6.png

App 黑白化实现探索,有一行代码实现的方案吗?

4631128adb2ad5cc27b3e3cddc458977.png

让我知道你“在看” 86ab4265f1e5b55500d58b6961f2b20c.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值