当前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的方法区中 调用时 将方法拿到栈中 执行完后 这个方法会出栈 然后新的方法方法进栈
随机推荐
- Elasticsearch---DSL搜索实践
Domain Specific Language 特定领域语言,基于JSON格式的数据查询,查询更灵活,有利于复杂查询 一.普通url路径参数搜索 数据准备 1.建立名字为 shop 的索引 2.手动 ...
- 【转载】Win10彻底格式化磁盘防止数据恢复的技巧
转载地址 注意 要尽量删除数据,请在运行cipher /w时关闭其他所有应用程序. 1.如果你在格式化磁盘后想要防止数据被恢复, Format 命令,而现在只需在其后添加 /P 参数,即可用随机数据覆 ...
- springCloud中的注册中心Nacos
springCloud中的注册中心Nacos 三个模块: 1.注册中心 2.服务提供者(生产者) 提供服务 3.服务消费者(消费者)调用服务 流程:消费者和生产者都要向注册中心注册,注册的是二者中服务 ...
- luogu4464:莫比乌斯反演,积性函数和伯努利数
题目链接:https://www.luogu.com.cn/problem/P4464 简记$gcd(x,y)=(x,y)$. 推式子: $\sum_{i=1}^{n}{(i,n)^xlcm(i,n) ...
- Android 开发学习进程0.28 腾讯TBS接入和相关问题
TBS 的接入和使用 TBS 的接入 腾讯TBS是X5内核的升级版,可以当作webview 来打开 网页,可以以用来打开docx doc pdf 等文件,这里主要使用的是文件功能. 依赖接入 api ...
- MySQL学习笔记(五)
倒数第二天!冲冲冲!!! 一.索引 一个表里面可以有多个索引. 1. 索引的作用:约束与加速查找 无索引:从前到后依次查找 有索引:会为索引列创造一个额外文件(以某种格式存储).在使用索引进行查找时, ...
- CVE-2016-5734-phpmyadmin-4.0.x-4.6.2-代码执行
参考 https://www.jianshu.com/p/8e44cb1b5b5b 漏洞原因 phpMyAdmin是一套开源的.基于Web的MySQL数据库管理工具.在其查找并替换字符串功能中,将用户 ...
- 通达OA 页面敏感信息-2013/2015版本
参考 http://wiki.0-sec.org/0day/%E9%80%9A%E8%BE%BEoa/4.html 漏洞影响 2013.2015版本 复现过程 POC: http://0-sec.or ...
- SQL驱动限制,导致插入失败
insert into TB_IF_ORDERS (DC_CD,JOB_DT,SEQ_NO,ORDER_KEY,ORDER_ID,ORDER_LINE_NUM,COMPANY_CD,CUST_CD,S ...
- Java小tips之命令行传参
在命令行运行主函数时,后缀字符串,则会储存在args[]数组中,这种方法可以在程序运行时,借助Main函数传参 主类书写不规范见谅 ```java public class hello{ public ...