Android启动流程源码解析(二)

Android启动流程源码解析(二)

在之前的Android启动流程源码解析(一)源码分析中,我们最后遗留下来一个问题。那就是我们的Activity的启动是啥时候处理的啊?上万行的分析,也没看到我们想要的onCreate啥的。其实就是resumeFocusedStacksTopActivities方法,所以我们这篇文章就从这个方法开始。

resumeFocusedStacksTopActivities

   boolean resumeFocusedStacksTopActivities() {
        return resumeFocusedStacksTopActivities(null, null, null);
    }

    boolean resumeFocusedStacksTopActivities(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        boolean result = false;
        if (targetStack != null && (targetStack.isTopStackOnDisplay()|| getTopDisplayFocusedStack() == targetStack)) {
            //******重点方法******如果当前的activitystack正好处于屏幕的顶部,那么直接调用将target设置到顶部显示
            result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }

        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            //标记是否已经显示在屏幕上
            boolean resumedOnDisplay = false;
            final ActivityDisplay display = mActivityDisplays.get(displayNdx);
            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = display.getChildAt(stackNdx);
                //获取到当前ActivityStack顶部正在运行的Activity
                final ActivityRecord topRunningActivity = stack.topRunningActivityLocked();
                if (!stack.isFocusableAndVisible() || topRunningActivity == null) {
                    continue;
                }
                if (stack == targetStack) {
                    //上面已经做过resume处理了,所以这里我们就不再做处理了
                    resumedOnDisplay |= result;
                    continue;
                }
                if (display.isTopStack(stack) && topRunningActivity.isState(RESUMED)) {
                    stack.executeAppTransition(targetOptions);
                } else {
                    resumedOnDisplay |= topRunningActivity.makeActiveIfNeeded(target);
                }
            }
            //如果仍然没有显示在屏幕上,那么就获取到屏幕当前持有焦点的ActivityStack,然后将activity显示在上面
            if (!resumedOnDisplay) {
                final ActivityStack focusedStack = display.getFocusedStack();
                if (focusedStack != null) {
                    focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
                }
            }
        }
        return result;
    }

这里我们只需要关注一个方法 resumeTopActivityUncheckedLocked ,这个方法也特别长,我们就拆分开,只关注重点方法即可

    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mInResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }
        boolean result = false;
        try {
            // Protect against recursion.
            mInResumeTopActivity = true;
            //***重点关注******
            result = resumeTopActivityInnerLocked(prev, options);
            final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
            if (next == null || !next.canTurnScreenOn()) {
                checkReadyForSleep();
            }
        } finally {
            mInResumeTopActivity = false;
        }

        return result;
    }

这里我们也只关注resumeTopActivityInnerLocked方法

    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
       ...  
       if (mResumedActivity != null) {
            //****重点方法 ****** 调用acitivity的pause方法
            pausing |= startPausingLocked(userLeaving, false, next, false);
        }
        ...
        //进行activity的创建处理
        mStackSupervisor.startSpecificActivityLocked(next, true, false);
        ...
    }

代码也很长,我们只提取了两个比较重要的函数,一个是调用onPause生命周期函数,另一个是调用onCreate生命周期函数的。

onPause的暂停过程

我们首先来看一下是如何一步步通过调度来执行onPause的生命周期调度的

//ActivityStack.java
    final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming, boolean pauseImmediately) {
        ...
        //当前正在显示的Activity
        ActivityRecord prev = mResumedActivity;
        //当前正在显示的Activity需要执行暂停操作了。
        //将其赋值给mPausingActivity成员变量。
        mPausingActivity = prev;
        mLastPausedActivity = prev;
        //Activity绑定了对应的APP?难道有不绑定的情况么?
        if (prev.attachedToProcess()) {
               ...  
                //******重点方法****
 mService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,prev.configChangeFlags, pauseImmediately));
            ...

重点方法已经标注出来了。我们先看看它的参数的创建过程。

PauseActivityItem.obtain
//PauseActivityItem.java
    //从池中取出一个PauseActivityItem类
    public static PauseActivityItem obtain(boolean finished, boolean userLeaving, int configChanges, boolean dontReport) {
        PauseActivityItem instance = ObjectPool.obtain(PauseActivityItem.class);
        if (instance == null) {
            instance = new PauseActivityItem();
        }
        instance.mFinished = finished;
        instance.mUserLeaving = userLeaving;
        instance.mConfigChanges = configChanges;
        instance.mDontReport = dontReport;
        return instance;
    }
//ObjectPool.java
    public static <T extends ObjectPoolItem> T obtain(Class<T> itemClass) {
        synchronized (sPoolSync) {
            @SuppressWarnings("unchecked")
            final ArrayList<T> itemPool = (ArrayList<T>) sPoolMap.get(itemClass);
            if (itemPool != null && !itemPool.isEmpty()) {
                return itemPool.remove(itemPool.size() - 1);
            }
            return null;
        }
    }

可以看到,对于PauseActivityItem的获取,是通过享元模式 来进行处理的。

回到主干。

这的mService是ActivityTaskManagerServicegetLifecycleManager方法返回的是ClientLifecycleManager对象。

    private final ClientLifecycleManager mLifecycleManager;
    mLifecycleManager = new ClientLifecycleManager();
    ClientLifecycleManager getLifecycleManager() {
        return mLifecycleManager;
    }
scheduleTransaction
//ClientLifecycleManager.java
    //调用一次生命周期的调度请求
    void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,@NonNull ActivityLifecycleItem stateRequest) throws RemoteException {
        final ClientTransaction clientTransaction = transactionWithState(client, activityToken,stateRequest);
        scheduleTransaction(clientTransaction);
    }
    //实际的调度方法
    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        transaction.schedule();
        if (!(client instanceof Binder)) {
            //回收
            transaction.recycle();
        }
    }
    //创建一个持有状态的事务类
    private static ClientTransaction transactionWithState(@NonNull IApplicationThread client,
            @NonNull IBinder activityToken, @NonNull ActivityLifecycleItem stateRequest) {
        final ClientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken);
        clientTransaction.setLifecycleStateRequest(stateRequest);
        return clientTransaction;
    }

这里最终会调用ClientTransaction对象的schedule方法。

//ClientTransaction.java
    public void schedule() throws RemoteException {
        mClient.scheduleTransaction(this);
    }

这里的mClient是一个IApplicationThread,其Server端是ActivityThread#ApplicationThread。所以最终调用的是ApplicationThreadscheduleTransaction方法

//ActivityThread.java
    public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            //会调用ActivityThread.scheduleTransaction方法->该方法位于ActivityThread的父类中
            ActivityThread.this.scheduleTransaction(transaction);
        }

//ClientTransactionHandler.java
    void scheduleTransaction(ClientTransaction transaction) {
        //执行预处理
        transaction.preExecute(this);
        //通过Handler机制发送事务请求
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }

Handler消息机制就不贴出来了,直接看其是怎么处理的。

//ActivityThread.java
    private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);

            case EXECUTE_TRANSACTION://执行生命周期的调度工作
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    mTransactionExecutor.execute(transaction);

当接收到Handler以后,会调用TransactionExecutorexecute()方法。

//TransactionExecutor.java
    public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        ...
        //循环遍历回调请求的所有状态,并在适当的时间执行它们
        executeCallbacks(transaction);
        //执行生命周期的改变
        executeLifecycleState(transaction);
    }

ClientTransaction存在两种事务,

  • 一种是通过setLifecycleStateRequest设置一个对象的事务类型,用于表示事务执行以后,客户端应该处于的生命周期状态
  • 一种是addCallback,增加对客户端的事务类型回调,对客户端一系列的回调。

这两个不同的类型,在这里就会存在不同的处理方法。对于第一种会在executeCallbacks中进行处理,第二种则会在executeLifecycleState中进行处理。

我们这儿的暂停,是通过第二种来进行设置的,所以我们直接看executeLifecycleState这个方法。

//TransactionExecutor.java
    //如果事务请求,则转换到最终状态
    private void executeLifecycleState(ClientTransaction transaction) {
        // ActivityStackSupervisor.java中进行了这个设置
        // final ActivityLifecycleItem lifecycleItem;
        //                if (andResume) {
        //                    lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
        //                } else {
        //                    lifecycleItem = PauseActivityItem.obtain();
        //                }
        //                clientTransaction.setLifecycleStateRequest(lifecycleItem);
        //所以这里的lifecycleItem可能是ResumeActivityItem或者PauseActivityItem或者其他的生命周期相关类
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        if (lifecycleItem == null) {
            //如果不是通过setLifecycleStateRequest设置的,那么该方法不需要处理,直接返回即可
            return;
        }
        //使用适当的参数执行最后的转换
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }

我们这里的lifecycleItem是我们刚才创建的PauseActivityItem,这里会执行其execute方法。

//PauseActivityItem.java
    @Override
    public void execute(ClientTransactionHandler client, IBinder token,  PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
        //这里的client,是Activity独享
        client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,"PAUSE_ACTIVITY_ITEM");
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

这里的client对象我们需要回退去跟踪一下

//ActivityThread.java
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
//TransactionExecutor.java
//在ActivityThread类中中调用了mTransactionExecutor = new TransactionExecutor(this)这个方法,其中的mTransactionHandler是ActivityThread本身
    public TransactionExecutor(ClientTransactionHandler clientTransactionHandler) {
        mTransactionHandler = clientTransactionHandler;
    }

所以说,最终调用的是ActivityThreadhandlePauseActivity方法

//ActivityThread.java
    public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,int configChanges, PendingTransactionActions pendingActions, String reason) {
        //获取对应的ActivityClientRecord对象
        ActivityClientRecord r = mActivities.get(token);
        if (r != null) {
            ...
            //***重点方法***,执行pause方法
            performPauseActivity(r, finished, reason, pendingActions);
            ...
        }
    }

    private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason,
                                        PendingTransactionActions pendingActions) {
        ...
        //****重点方法****
        performPauseActivityIfNeeded(r, reason);
        ...
        return shouldSaveState ? r.state : null;
    }
    private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
            ...
            r.activity.mCalled = false;
            //重点方法,通过Instrumentation调用onPause生命周期
            mInstrumentation.callActivityOnPause(r.activity);
            ...
    }

最终会通过Instrumentation调用callActivityOnPause方法。

   //Instrumentation.java
    public void callActivityOnPause(Activity activity) {
        activity.performPause();
    }
    //Activity.java
    final void performPause() {
        dispatchActivityPrePaused();
        mDoReportFullyDrawn = false;
        //管理的Fragment的处理
        mFragments.dispatchPause();
        mCalled = false;
        //调用了onPause生命周期方法
        onPause();
        writeEventLog(LOG_AM_ON_PAUSE_CALLED, "performPause");
        //设置mResumed为false,表示当前activity没有展示
        mResumed = false;
        //调用一些回调函数
        dispatchActivityPostPaused();
    }

到这里为止,原来在我们面前展示的那个Activity调用了其onPause方法。

Activity的创建过程

回到主线的resumeTopActivityInnerLocked方法中,当执行完startPausingLocked方法后,会调用mStackSupervisor.startSpecificActivityLocked方法

    //ActivityStackSupervisor.java
    void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
        //根据uid和pid,获取activity对应的进行和线程信息
        final WindowProcessController wpc =mService.getProcessController(r.processName, r.info.applicationInfo.uid);
        boolean knownToBeDead = false;
        if (wpc != null && wpc.hasThread()) {
            //如果进程和线程都存在,执行后面的代码
            try {
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            knownToBeDead = true;
        }
            //通过message进行进程的启动。
            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);
        }
    }

如果要启动的activity所在的进程和线程都存在,那么直接调用realStartActivityLocked方法进行启动,否则的话,就会调用Handler机制进行进程的创建。

realStartActivityLocked

    //真正执行Activity启动的方法
    boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc, boolean andResume, boolean checkConfig) throws RemoteException {
        //如果还有activity没有暂停,这里会直接返回false
        if (!mRootActivityContainer.allPausedActivitiesComplete()) {
            return false;
        }

        final TaskRecord task = r.getTaskRecord();
        final ActivityStack stack = task.getStack();
        //设置标志位,不再接收其他activity的resume的操作
        beginDeferResume();
        try {
           ...
                //创建了一个Activity事务
                final ClientTransaction clientTransaction = ClientTransaction.obtain(proc.getThread(), r.appToken);
                final DisplayContent dc = r.getDisplay().mDisplayContent;
                //增加一个要执行的事务LaunchActivityItem。
                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        System.identityHashCode(r), r.info,
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                        r.icicle, r.persistentState, results, newIntents,
                        dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                                r.assistToken));
                final ActivityLifecycleItem lifecycleItem;
                //设置其生命周期LifecycleStateRequest
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
                clientTransaction.setLifecycleStateRequest(lifecycleItem);
                //执行事务的调度
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
        ...
        proc.onStartActivity(mService.mTopProcessState, r.info);
        return true;
    }

在这个方法里面,创建了一个事务,在事务中增加了一个callback回调,然后通过setLifecycleStateRequest设置了一个生命周期,最后通过scheduleTransaction执行了调度。在前面的onPause中,我们梳理了整个调度的流程,最后会调用到LaunchActivityItemexecute,然后会调用生命周期所对应的ResumeActivityItemexecute

我们挨个看,先看LaunchActivityItem的调用

//LaunchActivityItem.java
    //一般会在TransactionExecutor中调用这个方法
    //ClientTransactionHandler实际是ActivityThread对象,所以这里会执行activitythread类中的handleLaunchActivity方法
    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
                        PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                mPendingResults, mPendingNewIntents, mIsForward,
                mProfilerInfo, client, mAssistToken);
        //调用activitythread类中的handleLaunchActivity方法
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

其本质调用的是ActivityThread中的handleLaunchActivity方法。

这部分的功能,我们在Android布局窗口绘制分析中进行过解析。这里不再往下进行解析了。

我们直接跳过这部分,来看看如果启动的activity所在的进程和线程都存在。会进行进程的创建工作。这部分我们后面专门再进行一篇关于进程创建的解析工作。

本文由 开了肯 发布!

同步公众号[开了肯]

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342