TaskView简述

TaskView是什么

首先看一下官方的注释(基于Android12.0.0_r3版本的代码分析):

View that can display a task
是一个可以展示Task的视图。那有什么用呢?简单来说就是跨进程来展示UI。就比如我有两个进程,进程A和进程B。我想在进程A中启动进程B的Activity,这时候就可以使用TaskView来实现这个功能。

接着再来说TaskView是什么?

TaskView 是SurfaceView的子类,并且实现了
SurfaceHolder.Callback, ShellTaskOrganizer.TaskListener, ViewTreeObserver.OnComputeInternalInsetsListener这三个接口

首先说一下SurfaceView,这个用过的人都有些印象,比如摄像头的录制展示可以用SurfaceView来展示或者是一些需要即时更新的UI可以通过SurfaceView来进行展示。换大多数人的说法就是挖了个洞,也确实是,如果要是保证效率,没必要做那么多没用的操作,有个捷径何尝不是个好事情~。
接着是 SurfaceHolder.Callback,注册了这个Callback,就能够接受到Surface改变的回调,经典的三个方法surfaceCreated,surfaceChangedsurfaceDestroyed,一般是和SurfaceView配合使用的。
说到这,可以把TaskView理解为一个SurfaceView。
接着说一下 ShellTaskOrganizer.TaskListener这个接口,这个就属于是WindowManager/Shell这一套的相关接口了。在系统的任务更改的时候,就能在这个监听中收到回调。在这里,TaskView是这个接口的实现类,那就说明,ShellTaskOrganizer对TaskView进行管理,当有消息来时,就会去通知给TaskView。
最后说一下ViewTreeObserver.OnComputeInternalInsetsListener这个接口,这个接口在源码中搜索了下,发现了一个熟悉的类VoiceInteractionSession,接触到的项目对于语音助手的使用就是基于这个类的相关交互的,往下翻,发现熟悉的onShowonHide方法等等。。。有点跑题了。布局完成的时候,如果实现了这个接口,就能够onComputeInternalInsets接受到回调,语音助手收到后回去进行自己的UI绘制。

TaskView的创建

创建还不好说么,直接new一个,开句玩笑。具体如何创建,还得看谷歌源生代码是怎么使用的。

/** Interface to create TaskView. */
@ExternalThread
public interface TaskViewFactory {/** Creates an {@link TaskView} */void create(@UiContext Context context, Executor executor, Consumer<TaskView> onCreate);
}

搜索TaskView的构造方法,发现TaskViewFactory,听名字就是一个TaskView的创建类,查看注释,更加确定就是通过这个接口来创建TaskView了。终归是一个接口,去看下具体实现。

/** Factory controller which can create {@link TaskView} */
public class TaskViewFactoryController {private final ShellTaskOrganizer mTaskOrganizer;private final ShellExecutor mShellExecutor;private final TaskViewFactory mImpl = new TaskViewFactoryImpl();public TaskViewFactoryController(ShellTaskOrganizer taskOrganizer,ShellExecutor shellExecutor) {mTaskOrganizer = taskOrganizer;mShellExecutor = shellExecutor;}public TaskViewFactory asTaskViewFactory() {return mImpl;}/** Creates an {@link TaskView} */public void create(@UiContext Context context, Executor executor, Consumer<TaskView> onCreate) {TaskView taskView = new TaskView(context, mTaskOrganizer);executor.execute(() -> {onCreate.accept(taskView);});}private class TaskViewFactoryImpl implements TaskViewFactory {@ExternalThreadpublic void create(@UiContext Context context,Executor executor, Consumer<TaskView> onCreate) {mShellExecutor.execute(() -> {TaskViewFactoryController.this.create(context, executor, onCreate);});}}
}

可以看到TaskViewFactoryController的内部类TaskViewFactoryImpl实现了TaskViewFactory这个接口,并且交给TaskViewFactoryController来进行TaskView的创建。到这里大概就知道了,创建TaskView时需要创建一个ShellTaskOrganizer和一个ShellExecutor对象,接着再来创建一个TaskView对象。这里留个猜测,等到TaskView启动的Activity的onCreate()执行后,才去创建TaskView对象。

再来看一下TaskView的构造函数干了些什么事情。

public TaskView(Context context, ShellTaskOrganizer organizer) {super(context, null, 0, 0, true /* disableBackgroundLayer */);mTaskOrganizer = organizer;mShellExecutor = organizer.getExecutor();setUseAlpha();getHolder().addCallback(this);// 用来打印警告的log,以及告诉关闭的方法名。要成对使用mGuard.open("release");
}

首先mTaskOrganizermShellExecutor在上面可以看到,都是在构造的时候需要的参数,接着setUseAlpha()方法是用来设置透明度的。下面getHolder().addCallback(this)是向其父类SurfaceView注册SurfaceHolder.Callback监听的。
到此为止,TaskView的创建暂时来个中场休息~


TaskView的使用

对于TaskView的使用,去启动界面使用startActivity方法即可,向其传递一个PendingIntent对象,就能够让其在TaskView中去启动一个其他的Activity。但是这里先说一下另一个比较重要的点,startActivity随后再说。这里说一下要进行注册的监听,也就是TaskView.Listener,该监听是需要TaskView的setListener方法去进行注册的。

TaskView.Listener

为什么要先说这个的?首先把状态的监听注册好,能够很好的去监听我们通过TaskView展示其他进程的Activity的状态,至少能够知道执行到了TaskView的哪一步,如果出现问题方便我们去很快的定位。
先看看这个监听都包含了哪些方法:

/** Callback for listening task state. */
public interface Listener {/** Called when the container is ready for launching activities. */default void onInitialized() {}/** Called when the container can no longer launch activities. */default void onReleased() {}/** Called when a task is created inside the container. */default void onTaskCreated(int taskId, ComponentName name) {}/** Called when a task visibility changes. */default void onTaskVisibilityChanged(int taskId, boolean visible) {}/** Called when a task is about to be removed from the stack inside the container. */default void onTaskRemovalStarted(int taskId) {}/** Called when a task is created inside the container. */default void onBackPressedOnTaskRoot(int taskId) {}
}

看一下官方的注释,这个监听就是用来监听Task的状态的。

onInitialized这个方法说明当前的容器已经准备好去启动Activity了,当TaskView收到了surfaceCreated【SurfaceHolder.Callback】的回调之后,便会去给注册的监听发送onInitialized的消息。
onTaskCreated这个方法在Task已经被创建并且放入容器时,回去收到这个回调,当TaskView收到onTaskAppeared【ShellTaskOrganizer.TaskListener】的回调后,会去告知Listener的onTaskCreated
onTaskVisibilityChanged这个方法在调用updateTaskVisibility()的方法时回去通知监听的可见性变化,也即surfaceCreated,surfaceDestroyedonTaskAppeared时会去更新可见性变化。
onReleased这个方法在容器不在启动Activity的时候进行调用,一般我们在使用完后可以手动去release()
onTaskRemovalStarted这个方法在Task在栈中即将移除时调用,即在onTaskVanished【ShellTaskOrganizer.TaskListener】回调后去执行。
onBackPressedOnTaskRoot当Task被创建并且放入容器时进行调用,即在onBackPressedOnTaskRoot【ShellTaskOrganizer.TaskListener】回调后去执行。

上面提到的 【ShellTaskOrganizer.TaskListener】 都是在ShellTaskOrganizer这个类分发下来的,之后也会再继续整理整体的流程。而实现SurfaceHolder.Callback的三个方法,是在其父类另一个父类SurfaceView进行可见性调整的时候,会向其下发对应的回调。

startActivity

TaskView归根到底,还是去起一个Activity,只不过展示的位置变了。先看下源码:

/*** Launch a new activity.** @param pendingIntent Intent used to launch an activity.* @param fillInIntent Additional Intent data, see {@link Intent#fillIn Intent.fillIn()}* @param options options for the activity.* @param launchBounds the bounds (window size and position) that the activity should be*                     launched in, in pixels and in screen coordinates.*/
public void startActivity(@NonNull PendingIntent pendingIntent, @Nullable Intent fillInIntent,@NonNull ActivityOptions options, @Nullable Rect launchBounds) {prepareActivityOptions(options, launchBounds);try {pendingIntent.send(mContext, 0 /* code */, fillInIntent,null /* onFinished */, null /* handler */, null /* requiredPermission */,options.toBundle());} catch (Exception e) {throw new RuntimeException(e);}
}

需要传入四个参数,分别是一个PendingIntent,Intent,ActivityOptions和Rect。第一个参数是即将启动的Activity的Intent信息,第二个参数是Intent的补充信息,第三个参数是Activity的一些参数,最后一个参数是展示的大小以及位置。
prepareActivityOptions会将Rect数据存储到ActivityOptions当中去并且向ShellTaskOrganizer注册自身【ShellTaskOrganizer.TaskListener】。

TaskView.Listener # onTaskCreated()

这里先简单记录一下和onTaskCreated()方法的相关流程。
所谓的TaskView,现在终于算是到了Task了,到我现在分析的这个位置,Task类持有一个ActivityTaskManagerService对象,ActivityTaskManagerService又会持有一个 TaskOrganizerController对象,随后去进行跨进程通信。这里的数理逻辑是倒着来进行分析的。

#mermaid-svg-qCdsktUYx9OBWbT7 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-qCdsktUYx9OBWbT7 .error-icon{fill:#552222;}#mermaid-svg-qCdsktUYx9OBWbT7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-qCdsktUYx9OBWbT7 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-qCdsktUYx9OBWbT7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-qCdsktUYx9OBWbT7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-qCdsktUYx9OBWbT7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-qCdsktUYx9OBWbT7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-qCdsktUYx9OBWbT7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-qCdsktUYx9OBWbT7 .marker.cross{stroke:#333333;}#mermaid-svg-qCdsktUYx9OBWbT7 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-qCdsktUYx9OBWbT7 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-qCdsktUYx9OBWbT7 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-qCdsktUYx9OBWbT7 .actor-line{stroke:grey;}#mermaid-svg-qCdsktUYx9OBWbT7 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-qCdsktUYx9OBWbT7 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-qCdsktUYx9OBWbT7 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-qCdsktUYx9OBWbT7 .sequenceNumber{fill:white;}#mermaid-svg-qCdsktUYx9OBWbT7 #sequencenumber{fill:#333;}#mermaid-svg-qCdsktUYx9OBWbT7 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-qCdsktUYx9OBWbT7 .messageText{fill:#333;stroke:#333;}#mermaid-svg-qCdsktUYx9OBWbT7 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-qCdsktUYx9OBWbT7 .labelText,#mermaid-svg-qCdsktUYx9OBWbT7 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-qCdsktUYx9OBWbT7 .loopText,#mermaid-svg-qCdsktUYx9OBWbT7 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-qCdsktUYx9OBWbT7 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-qCdsktUYx9OBWbT7 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-qCdsktUYx9OBWbT7 .noteText,#mermaid-svg-qCdsktUYx9OBWbT7 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-qCdsktUYx9OBWbT7 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-qCdsktUYx9OBWbT7 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-qCdsktUYx9OBWbT7 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-qCdsktUYx9OBWbT7 .actorPopupMenu{position:absolute;}#mermaid-svg-qCdsktUYx9OBWbT7 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-qCdsktUYx9OBWbT7 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-qCdsktUYx9OBWbT7 .actor-man circle,#mermaid-svg-qCdsktUYx9OBWbT7 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-qCdsktUYx9OBWbT7 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} TaskView.Listener ShellTaskOrganizer.TaskListener TaskOrganizer ITaskOrganizer TaskOrganizerController.TaskOrganizerCallbacks TaskOrganizerController.TaskOrganizerState TaskOrganizerController Task Task通过其持有的ActivityTaskMangerService对象,再用其对象持有的TaskOrganizerController进行分发 sendTaskAppeared onTaskAppeared onTaskAppeared onTaskAppeared 进行跨进程通信 onTaskAppeared onTaskAppeared onTaskCreated TaskView.Listener ShellTaskOrganizer.TaskListener TaskOrganizer ITaskOrganizer TaskOrganizerController.TaskOrganizerCallbacks TaskOrganizerController.TaskOrganizerState TaskOrganizerController Task

在这个流程图中,以TaskOrganizerController作为一个参考线,在这个流程图的左侧,全都是属于客户端的范畴,而右侧是服务端的范畴,服务端跨进程向客户端进行数据的发送,我们在收到对应的回调后再进行相关的处理。
而正如其名,TaskOrganizerController就是用来进行Task分发的控制的。

TaskView简述相关推荐

  1. 简述计算机科学的核心内容,北京大学-计算机科学与技术(2018秋)作业及复习

    59.(第十章)外排序是指在排序前后,数据在外存上,排序时数据调入内存进行的排序方法. 60.(第十章)在选择排序.冒泡排序.归并排序中, 归并排序是空间复杂度最大的. 三.简答和程序题(共10题,每 ...

  2. 设计模式学习1:设计模式简述和设计模式原则

    设计模式简述 什么是设计模式? 软件工程中,设计模式(design pattern)是对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案. 设计模式的目的: 代码高可用(相同作用的代码能重复 ...

  3. Java中常见的锁简述

    在Java的应用中,或多或少的都会接触到一些锁,那么问题就来了,在Java中,常见的锁有哪些,都有什么样的作用?? 这里给大家简单的简述一下这些学常见的锁. 本文件所涉及到的锁: 1.公平锁 / 非公 ...

  4. 简述DataInputStream和DataOuputStream

    2019独角兽企业重金招聘Python工程师标准>>> Java开发中经常会用到IO流,那么就会碰到DataInputStream和DataOuputStream这两个包装类.下面就 ...

  5. 简要叙述matlab的含义,1,简述MATLAB组成部分? 2,说明使用M文件编辑/调试器的方法和优点? 3,存储在工作空间中的数组能编辑吗...

    匿名用户 1级 2012-05-17 回答 我也考这个....祝你好运 1,简述MATLAB组成部分? (1)开发环境(development Environment); (2)MATLAB数学函数库 ...

  6. 简述Linux和Windows下Python搭建步骤

    简述就Windows和Linux环境下安装Python的步骤. Python环境搭建首先到官网(www.python.org)下载相应的安装版本.主要分为Windows和Linux两种: 一.Linu ...

  7. 简述 OAuth 2.0 的运作流程

    本文将以用户使用 github 登录网站留言为例,简述 OAuth 2.0 的运作流程. 假如我有一个网站,你是我网站上的访客,看了文章想留言表示「朕已阅」,留言时发现有这个网站的帐号才能够留言,此时 ...

  8. 简述机器指令与微指令之间的关系_自考《计算机组成原理》模拟试题(一)

    一.单项选择题(本大题共 25小题,每小题1分,共25分)在每小题列出的四个选项中只有一个选项是符合题目要求的,请将正确选项前的字母填在题后的括号内. 1.-0的8位二进制补码是( ) A.10000 ...

  9. day1简述、输入输出、运算符、条件语句、文件读写、三元运算

    文章目录 1.Python 简述 2.变量 3.输入输出 4.数据运算 5. 条件语句 if..else.elif 循环语句 for.while 6.文件读写 7.三元运算 1.Python 简述   ...

最新文章

  1. IOS开发中多线程的使用
  2. GDI+中发生一般性错误
  3. 教你写出可读性高的Python代码
  4. php将数字转化为中文大写人民币格式
  5. maven(6)仓库
  6. windows7下安装php的imagick和imagemagick扩展教程
  7. MongoDB Replication
  8. Linux指令:grep指令详解1
  9. 2020 数学建模国赛 B 题参考思路
  10. 边缘计算在物联网领域的发展前景
  11. 1082 射击比赛(JAVA)
  12. office安装双击setup后点击‘立即安装’无反应(闪退)
  13. 美团商品平台化之路—关于架构原则的思考
  14. [托业]TOEIC词汇汇总(完整篇)4
  15. Dell 服务器错误代码
  16. “云”中智控 IT管理新境界
  17. 怎么在pc端浏览器调试移动端页面
  18. 器件——TCRT5000参数与实际设计应用
  19. 使用PhoenixSuit.exe刷机失败的解决办法
  20. 关于mybatis中mapper文件resultMap中collection和association的使用

热门文章

  1. 十分钟掌握折半查找法,
  2. 学习笔记——Kaggle_Digit Recognizer (Random Forest算法 Python实现)
  3. 当年明月《明朝那些事儿》读书笔记
  4. Linux sed实战
  5. requests之get请求带参数示例详解
  6. kali系统渗透window实现屏幕监控
  7. Elasticsearch一网打通
  8. id returned 1 existed:让人发疯的devc++报错
  9. The Shawshank Redemption-12
  10. vba 连接access数据库 方法二