Activity启动源码分析(5)-- onStop,onDestroy探寻

前四篇的内容在这里。
Activity启动源码分析--总篇
Activity启动源码分析(1)--预启动过程
Activity启动源码分析(2)--Pause过程
Activity启动源码分析(3)-- 新app进程创建过程
Activity启动源码分析(4)-- Activity B创建过程

1.目的

这个是这个启动的最后一篇,讲Activity生命周期里面回调的最后几个方法。前面已经讲到了onCreateonStartonResumeonPause。还差onStop,onDestroy,onRestart。看一下Activity启动过程中,他们究竟藏在哪里。
这篇结束后,Activity的几个主要生命周期就都介绍了。当然,读者也可以继续拓展其他方法。
onStop还能算在这个启动过程中,onDestroy,onRestart其实就没多大关系了。下面会分开讲。

2.OnStop

还是先放图。

Stop过程

接着上篇,
ActivityThread

        public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
            String reason) {
        ...
        //onResume执行完后,会在空闲时执行Idler
        Looper.myQueue().addIdleHandler(new Idler());
    }

IdleHandler是MessageQueue类里的一个借口,messages为空的时候就会执行IdleHandler。看下Idler是怎么实现queueIdle()的。
ActivityThread

    private class Idler implements MessageQueue.IdleHandler {
        @Override
        public final boolean queueIdle() {
            ...
                mNewActivities = null;
                //这就相当眼熟了,我们直接往AMS去找
                IActivityManager am = ActivityManager.getService();
                ActivityClientRecord prev;
                do {
                    if (localLOGV) Slog.v(
                        TAG, "Reporting idle of " + a +
                        " finished=" +
                        (a.activity != null && a.activity.mFinished));
                    if (a.activity != null && !a.activity.mFinished) {
                        try {
                            am.activityIdle(a.token, a.createdConfig, stopProfiling);
                            a.createdConfig = null;
                        } catch (RemoteException ex) {
                            throw ex.rethrowFromSystemServer();
                        }
                    }
                    prev = a;
                    a = a.nextIdle;
                    prev.nextIdle = null;
                } while (a != null);
            }
            ...
            return false;
        }
    }

ActivityManagerService

    @Override
    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
        final long origId = Binder.clearCallingIdentity();
        synchronized (this) {
            ActivityStack stack = ActivityRecord.getStackLocked(token);
            if (stack != null) {
                ActivityRecord r =
                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
                                false /* processPausingActivities */, config);
                if (stopProfiling) {
                    if ((mProfileProc == r.app) && mProfilerInfo != null) {
                        clearProfilerLocked();
                    }
                }
            }
        }
        Binder.restoreCallingIdentity(origId);
    }

ActivityStackSupervisor

    @GuardedBy("mService")
    final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
            boolean processPausingActivities, Configuration config) {
        ...

        //找到当前不在界面上为Pause状态的Activity
        // Atomically retrieve all of the other things to do.
        final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(r,
                true /* remove */, processPausingActivities);
        NS = stops != null ? stops.size() : 0;
        if ((NF = mFinishingActivities.size()) > 0) {
            finishes = new ArrayList<>(mFinishingActivities);
            mFinishingActivities.clear();
        }

        if (mStartingUsers.size() > 0) {
            startingUsers = new ArrayList<>(mStartingUsers);
            mStartingUsers.clear();
        }

        // Stop any activities that are scheduled to do so but have been
        // waiting for the next one to start.
        for (int i = 0; i < NS; i++) {
            r = stops.get(i);
            final ActivityStack stack = r.getStack();
            if (stack != null) {
                //Pause的Activitiy正在finish状态,这里自然不是
                if (r.finishing) {
                    stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false,
                            "activityIdleInternalLocked");
                } else {
                    //走你
                    stack.stopActivityLocked(r);
                }
            }
        }

        //onDestory会在这调用正在fininshing的Activity,是mFinishingActivities维护的。但是在前面没有看到往mFinishingActivities添加成员的地方
        // Finish any activities that are scheduled to do so but have been
        // waiting for the next one to start.
        for (int i = 0; i < NF; i++) {
            r = finishes.get(i);
            final ActivityStack stack = r.getStack();
            if (stack != null) {
                activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");
            }
        }
        ...
    }

    final ArrayList<ActivityRecord> processStoppingActivitiesLocked(ActivityRecord idleActivity,
            boolean remove, boolean processPausingActivities) {
        ArrayList<ActivityRecord> stops = null;

        final boolean nowVisible = allResumedActivitiesVisible();
        for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) {
            ...
            if (remove) {
                final ActivityStack stack = s.getStack();
                final boolean shouldSleepOrShutDown = stack != null
                        ? stack.shouldSleepOrShutDownActivities()
                        : mService.isSleepingOrShuttingDownLocked();
                //非显示状态
                if (!waitingVisible || shouldSleepOrShutDown) {
                    //处于Pause
                    if (!processPausingActivities && s.isState(PAUSING)) {
                        // Defer processing pausing activities in this iteration and reschedule
                        // a delayed idle to reprocess it again
                        removeTimeoutsForActivityLocked(idleActivity);
                        scheduleIdleTimeoutLocked(idleActivity);
                        continue;
                    }

                    if (DEBUG_STATES) Slog.v(TAG, "Ready to stop: " + s);
                    if (stops == null) {
                        stops = new ArrayList<>();
                    }
                    //添加返回
                    stops.add(s);
                    mStoppingActivities.remove(activityNdx);
                }
            }
        }

        return stops;
    }

ActivityStack

    private boolean adjustFocusToNextFocusableStack(String reason, boolean allowFocusSelf) {
        final ActivityStack stack =
                mStackSupervisor.getNextFocusableStackLocked(this, !allowFocusSelf);
        final String myReason = reason + " adjustFocusToNextFocusableStack";
        if (stack == null) {
            return false;
        }

        final ActivityRecord top = stack.topRunningActivityLocked();

        if (stack.isActivityTypeHome() && (top == null || !top.visible)) {
            // If we will be focusing on the home stack next and its current top activity isn't
            // visible, then use the move the home stack task to top to make the activity visible.
            return mStackSupervisor.moveHomeStackTaskToTop(reason);
        }

        stack.moveToFront(myReason);
        return true;
    }

    final void stopActivityLocked(ActivityRecord r) {
        ...
                //再眼熟不过,让ClientHandler去执行StopActivityItem了。
                mService.getLifecycleManager().scheduleTransaction(r.app.thread, r.appToken,
                        StopActivityItem.obtain(r.visible, r.configChangeFlags));
        ...
    }

这里从LifecycleManagerApp传递的过程前面已描述两次,这里不再赘述。
StopActivityItem

    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
        client.handleStopActivity(token, mShowWindow, mConfigChanges, pendingActions,
                true /* finalStateRequest */, "STOP_ACTIVITY_ITEM");
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

ActivityThread

    @Override
    public void handleStopActivity(IBinder token, boolean show, int configChanges,
            PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) {
        ...
        performStopActivityInner(r, stopInfo, show, true /* saveState */, finalStateRequest,
                reason);

        ...
    }

    private void performStopActivityInner(ActivityClientRecord r, StopInfo info, boolean keepShown,
            boolean saveState, boolean finalStateRequest, String reason) {
        ...
            if (!keepShown) {
                callActivityOnStop(r, saveState, reason);
            }
        ...
    }

    private void callActivityOnStop(ActivityClientRecord r, boolean saveState, String reason) {
        // Before P onSaveInstanceState was called before onStop, starting with P it's
        // called after. Before Honeycomb state was always saved before onPause.
        final boolean shouldSaveState = saveState && !r.activity.mFinished && r.state == null
                && !r.isPreHoneycomb();
        final boolean isPreP = r.isPreP();
        if (shouldSaveState && isPreP) {
            callActivityOnSaveInstanceState(r);
        }

        try {
            //这里可以看到Stop方法的调用了
            r.activity.performStop(false /*preserveWindow*/, reason);
        } catch (SuperNotCalledException e) {
            throw e;
        } catch (Exception e) {
            if (!mInstrumentation.onException(r.activity, e)) {
                throw new RuntimeException(
                        "Unable to stop activity "
                                + r.intent.getComponent().toShortString()
                                + ": " + e.toString(), e);
            }
        }
        r.setState(ON_STOP);

        if (shouldSaveState && !isPreP) {
            callActivityOnSaveInstanceState(r);
        }
    }

可以从上面看到,onStop实在MessageQueue空闲才会调用。不像onPuase,onResume一定会被调用。

3.OnDestroy

从之前见到的方法里,唯一好像与onDestroy相关的。是ActivityStackSupervisor.mFinishingActivities。但是启动流程里没有见到正常赋值的地方啊,所以全局搜索一下,猜测一下是否有DestroyActivityItem这个类,果然是有的。再往回推调用链,可以看到正常调用有找到两处,这里单列一下System_server端的调用关系:

对应App手动调用finish方法:
->ActivityManagerService:finishActivity
->ActivityStack:requestFinishActivityLocked
->ActivityStack:finishActivityLocked
->ActivityStack:finishCurrentActivityLocked
->ActivityStack:destroyActivityLocked

还有一个是

调用处可以参考第三篇Activity启动源码分析(3)-- 新app进程创建过程,在ActivityThread.attach有一个GcWatcher,内存占用大于3/4就会触发
->ActivityManagerService:releaseSomeActivities
->ActivityStackSupervisor:releaseSomeActivitiesLocked
->ActivityStack:releaseSomeActivitiesLocked
->ActivityStack:destroyActivityLocked

这篇的话,有看过Pause过程的话,是相当容易理解的。因为这里调用方式都一致。不会有上一篇app进程创建过程设计过程那么复杂。当然,我的文章只能描述其中一部分,还有大部分需要读者再从相关文章拓展。

其他地方看着都是异常时调用,还有系统强杀。所以onDestroy和onCreate一定会成对调用吗?并不是的,onDestroy并不一定会被调用。正常的流程下,只有在调用了finish后3/4内存占用后触发GC才调用了。所以反注册一定需要很是小心。

推荐的一种写法是

    @Override
    protected void onStop() {
        super.onStop();
        if(isFinishing()){
            //unRegister
        }
    }

3.OnRestart

在上一篇,我们有把cycleToPath具体分析。其实在这个里面
TransactionExecutorHelper

    public IntArray getLifecyclePath(int start, int finish, boolean excludeLastState) {
        ...
        //如果是从大的生命周期往小的生命周期变化,如onStop到onResume
        else { // finish < start, can't just cycle down
            if (start == ON_PAUSE && finish == ON_RESUME) {
                // Special case when we can just directly go to resumed state.
                mLifecycleSequence.add(ON_RESUME);
            } else if (start <= ON_STOP && finish >= ON_START) {
                // Restart and go to required state.

                //这里看到,最大也就是到onStop,并没有调用onDestroy方法
                // Go to stopped state first.
                for (int i = start + 1; i <= ON_STOP; i++) {
                    mLifecycleSequence.add(i);
                }
                //然后调用了Restart
                // Restart
                mLifecycleSequence.add(ON_RESTART);
                // Go to required state
                for (int i = ON_START; i <= finish; i++) {
                    mLifecycleSequence.add(i);
                }
            } else {
                // Relaunch and go to required state

                // Go to destroyed state first.
                for (int i = start + 1; i <= ON_DESTROY; i++) {
                    mLifecycleSequence.add(i);
                }
                // Go to required state
                for (int i = ON_CREATE; i <= finish; i++) {
                    mLifecycleSequence.add(i);
                }
            }
        }

        //移除了onResume
        // Remove last transition in case we want to perform it with some specific params.
        if (excludeLastState && mLifecycleSequence.size() != 0) {
            mLifecycleSequence.remove(mLifecycleSequence.size() - 1);
        }

        return mLifecycleSequence;
    }

一言蔽之,就是onDestroy没有调用的时候,Activity的状态由大变小,就会走onRestart。

那生命周期都已经见到了,这六篇博客,着重从进程的关系,App的创建,Activity生命周期回调的几个点,分析了Activity的启动流程。当然,只是挑了一个比较关键的流程进行分析。若是从细节分析,如结合Task_Flag等,会有无穷尽的细节可以分析。这里只是帮读者梳理一个可以切入分析的角度。有兴趣的可以继续深挖,学而有涯而识无涯,望于诸君砥砺前行。多谢各位~

参考文档:

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

推荐阅读更多精彩内容