前言

在前文中已经讲到.

  1. Launcher拉起新的Activity,并在ATMS中执行pause Activity的操作,以及当前Activity执行Pause的流程.
  2. 在当前Activity执行pause时同步执行拉起新进程操作.

本文主要讲当前Activity已经执行完Pause操作,调用ATMS的activityPaused接口,告知当前Activity已经暂停成功了的流程.

详细流程分析

PauseActivityItem执行postExecute时,就会调用ActivityTaskManager.getService().activityPaused(token);这个方法通过binder调用到ATMS的activityPaused.

activityPaused:1843, ActivityTaskManagerService

    public final void activityPaused(IBinder token) {
synchronized (mGlobalLock) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityPaused");
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
if (r != null) {
r.activityPaused(false);
}
}
Binder.restoreCallingIdentity(origId);
}

这里首先通过token去获取了当前Pause的Activity在ATMS中对应的ActivityRecord实例,然后调用

ActivityRecord的activityPaused.

todo:Activity,ActivityRecord,token,stack,task之间的关系.

activityPaused:4930, ActivityRecord

void activityPaused(boolean timeout) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE,
"Activity paused: token=" + appToken + ", timeout=" + timeout); final ActivityStack stack = getStack();

首先查找当前的ActivityRecord对应的ActivityStack

        if (stack != null) {
removePauseTimeout(); if (stack.mPausingActivity == this) {
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + this
+ (timeout ? " (due to timeout)" : " (pause complete)"));
mAtmService.deferWindowLayout();
try {
stack.completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
} finally {
mAtmService.continueWindowLayout();
}
return;

如果stack正在pausing的Activity是当前Activity,那么调用stack.completePauseLocked去resume下一个待resume的activity.

            } else {
if (isState(PAUSING)) {
setState(PAUSED, "activityPausedLocked");
if (finishing) {
if (DEBUG_PAUSE) Slog.v(TAG,
"Executing finish of failed to pause activity: " + this);
completeFinishing("activityPausedLocked");
}
}
}

如果当前在pausing的activity不是当前的这个Activity.那么做一些状态的处理.(假设Activity a pause但是超时了,那么在超时的时候就会调用paused操作.此时又把当前resume的Activity pause,而 a Activity有回调了activityPaused接口就会进入这个分支.)

        }

        mRootWindowContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
}

如果当前Activity的堆栈为空,或者当前pausing Activity不是当前这个Activity,那么还要调用mRootWindowContainerensureActivitiesVisible.

这里pausing Activity就是当前这个Activity,所以执行stack.completePauseLocked

completePauseLocked:1166, ActivityStack

void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
ActivityRecord prev = mPausingActivity;
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev); if (prev != null) {
prev.setWillCloseOrEnterPip(false);
final boolean wasStopping = prev.isState(STOPPING);
prev.setState(PAUSED, "completePausedLocked");
if (prev.finishing) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
prev = prev.completeFinishing("completePausedLocked");
} else if (prev.hasProcess()) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev
+ " wasStopping=" + wasStopping
+ " visibleRequested=" + prev.mVisibleRequested);
if (prev.deferRelaunchUntilPaused) {
// Complete the deferred relaunch that was waiting for pause to complete.
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev);
prev.relaunchActivityLocked(prev.preserveWindowOnDeferredRelaunch);
} else if (wasStopping) {
// We are also stopping, the stop request must have gone soon after the pause.
// We can't clobber it, because the stop confirmation will not be handled.
// We don't need to schedule another stop, we only need to let it happen.
prev.setState(STOPPING, "completePausedLocked");
} else if (!prev.mVisibleRequested || shouldSleepOrShutDownActivities()) {
// Clear out any deferred client hide we might currently have.
prev.setDeferHidingClient(false);
// If we were visible then resumeTopActivities will release resources before
// stopping.
prev.addToStopping(true /* scheduleIdle */, false /* idleDelayed */,
"completePauseLocked");
}
} else {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev);
prev = null;
}
// It is possible the activity was freezing the screen before it was paused.
// In that case go ahead and remove the freeze this activity has on the screen
// since it is no longer visible.
if (prev != null) {
prev.stopFreezingScreenLocked(true /*force*/);
}
mPausingActivity = null;
}

先获取当前Activity栈中待pause的Activity,执行一些Activity pause后的收尾工作.

        if (resumeNext) {
final ActivityStack topStack = mRootWindowContainer.getTopDisplayFocusedStack();
if (topStack != null && !topStack.shouldSleepOrShutDownActivities()) {
mRootWindowContainer.resumeFocusedStacksTopActivities(topStack, prev, null);
} else {
checkReadyForSleep();
final ActivityRecord top = topStack != null ? topStack.topRunningActivity() : null;
if (top == null || (prev != null && top != prev)) {
// If there are no more activities available to run, do resume anyway to start
// something. Also if the top activity on the stack is not the just paused
// activity, we need to go ahead and resume it to ensure we complete an
// in-flight app switch.
mRootWindowContainer.resumeFocusedStacksTopActivities();
}
}
}

如果需要resume 下一个activity,那么调用mRootWindowContainer.resumeFocusedStacksTopActivities去resume它.

上面两个不同参数的resumeFocusedStacksTopActivities方法的区别在于第一种是确定要拉起哪个堆栈中的Activity,另一个是要从所有的显示区域去找一个需要显示的堆栈,如果找不到的话则拉起Launcher.

当前Activity的onPause执行完后,调用Paused接口的更多相关文章

  1. 用一个bat文件调用另外两个bat文件,当1.bat执行完后再执行2.bat

    用一个bat文件调用另外两个bat文件,当1.bat执行完后再执行2.bat 摘自:https://zhidao.baidu.com/question/492732911.html @echo off ...

  2. 在Struts.xml中的result元素指的是:指定动作类的动作方法执行完后的结果视图.

    result结果集 上一篇文章主要讲Struts2框架(4)---Action类访问servlet这篇主要讲result结果集 在Struts.xml中的result元素指的是:指定动作类的动作方法执 ...

  3. vue在一个方法执行完后再执行另一个方法

    vue在一个方法执行完后执行另一个方法 用Promise来实现.Promise是ES6的新特性,用于处理异步操作逻辑,用过给Promise添加then和catch函数,处理成功和失败的情况 ES7中新 ...

  4. 有三个线程,a、b、c,a打印“T1”,b打印“T2”,c打印“T3”,a执行完后,b执行;b执行完后,c执行。如此循环100遍

    有三个线程,a.b.c,a打印“T1”,b打印“T2”,c打印“T3”,a执行完后,b执行:b执行完后,c执行.如此循环100遍. package com.company; /** * 测试三个线程协 ...

  5. T100——作业action执行其他P作业,后台背景执行完后才能继续操作改作业

    范例:如axmt500订单,查询开单占用量: 客制作业cxmp500,通过参数-订单号,查询该订单下的料件,目前有库存量.开单占用量.库存可用量,查询后更新到该订单下的单身对应栏位: 现在axmt50 ...

  6. iOS AFNetWorking中block执行完后再执行其它操作

    需求:同时进行两次网络请求,网络请求是异步的,在网络请求成功后进行其它的操作.两个网络请求是这样,一个网络请求中block执行完之后,再进行其它操作,也是一样的原理,只是这时候不需要线程组了,只需要信 ...

  7. 现在有T1、T2、T3三个线程,怎样保证T2在T1执行完后执行,T3在T2执行完后执行?使用Join

    public class TestJoin { public static void main(String[] args) { Thread t1 = new Thread(new T1(), &q ...

  8. C#子线程执行完后,调用主线程的方法

    private delegate void CheckVersionNumber_CallBack(string str);//定义一个为委托 用于 检测版本 //检测版本private void m ...

  9. 对象内存空间 在创建对象后 运行时 会把对象的方法放到jvm的方法区中 调用时 将方法拿到栈中 执行完后 这个方法会出栈 然后新的方法方法进栈

随机推荐

  1. 两年Java,去字节跳动写Python和Go

    前言 2019年5月,在收到offer邮件的那一刻,我仍然不敢相信自己这一番际遇.经历了七场面试,终于得偿所望,拿到了字节跳动的offer. 做加入大厂的决定并不是巧合.在多年的职业生涯里,我曾多次对 ...

  2. ElasticSearch URI 查询

    公号:码农充电站pro 主页:https://codeshellme.github.io 1,URI 查询格式 URI 查询的一般格式如下: GET /index_name/_search?q=key ...

  3. iOS拍照之系统拍照

    拍照在App中使用频次高,入门级别直接调用系统拍照 思路: 系统拍照使用UIImagePickerController 1.设置下plist,否则没权限,报错 2.判断摄像头,获取权限,否则弹出界面黑 ...

  4. idea没有错误提示的解决方法(一直处于错误分析中)

    仅作记录,以防再次发生却不记得. 原文链接:https://blog.csdn.net/a755199443/article/details/90084316 问题描述:idea没有自动报错.例如随便 ...

  5. IO、NIO、BIO的区别

    我们首先得明白什么是同步,异步,阻塞,非阻塞,只有这几个单个概念理解清楚了,然后在组合理解起来,就相对比较容易了. IO模型主要分类: 同步(synchronous) IO和异步(asynchrono ...

  6. es6 快速入门 系列

    es6 快速入门(未完结,持续更新中...) 前言 为什么要学习es6 es6对于所有javaScript开发者来说,非常重要 未来,es6将构成javaScript应用程序的基础 es6中很多特性, ...

  7. 力扣119. 杨辉三角 II

    原题 1 class Solution: 2 def getRow(self, rowIndex: int) -> List[int]: 3 ans = [1] 4 for i in range ...

  8. POJ-2236(并查集)

    Wireless NetWork POJ-2236 需要注意这里的树的深度需要初始化为0. 而且,find函数需要使用路径压缩,这里的unint合并函数也使用了优化(用一开始简单的合并过不了). #i ...

  9. OpenCV计算机视觉学习(13)——图像特征点检测(Harris角点检测,sift算法)

    如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 前言 ...

  10. 九. SpringCloud Stream消息驱动

    1. 消息驱动概述 1.1 是什么 在实际应用中有很多消息中间件,比如现在企业里常用的有ActiveMQ.RabbitMQ.RocketMQ.Kafka等,学习所有这些消息中间件无疑需要大量时间经历成 ...