setZOrderOnTop(true) 以修改 mSubLayer

简介: q

LayoutInflater 布局填充阶段,按既有的布局填充流程,将 SurfaceView 构造并加入到视图树的某个结点;接下来,根布局会通过深度遍历依次执行 onAttachedToWindow() 处理视图挂载窗口的事件:

// /frameworks/base/core/java/android/view/SurfaceView.java
@Override
protected void onAttachedToWindow() {

// ...
mParent.requestTransparentRegion(SurfaceView.this);   // 1.
ViewTreeObserver observer = getViewTreeObserver();
observer.addOnPreDrawListener(mDrawListener);         // 2.

}

@UnsupportedAppUsage
private final ViewTreeObserver.OnPreDrawListener mDrawListener = new ViewTreeObserver.OnPreDrawListener() {

@Override
public boolean onPreDraw() {
    updateSurface();                                 // 3.
    return true;
}

};

protected void updateSurface() {
// ...
mSurfaceSession = new SurfaceSession();
mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession); // 4
//...
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
步骤 1 中,SurfaceView 会向父视图依次向上请求创造一份透明区域,根视图统计到最终的信息后,通过 Binder 通知 WindowManagerService 将对应区域设置为透明。

步骤 2、3、4 是在同一个方法的调用栈中,由此可见,SurfaceView 向系统请求透明区域后,会立即创建一个与绘图表面的连接 SurfaceSession ,并创建一个对应的控制器 SurfaceControl,便于对这个独立的绘图表面进行直接通信。

由此可见,Android 自有的视图树体系中,SurfaceView 作为一个普通的 View 被挂载上去之后,通过 Binder 通信,WindowManagerService 将其所在区域设置为透明(挖洞);并建立了与独立绘图表面的连接,后续便可与其直接通信。

  1. 子图层类型

在阐述绘制流程之前,读者需简单了解 子图层类型 的概念。

上文说到,SurfaceView 的绝大多数使用场景中,其 z 轴的位置通常是在页面的 最下方 。但在实际开发中,随着业务场景复杂度的上升,仍然有部分场景是无法被满足的,比如:在页面的最上方播放一条全屏的视频广告。

因此,SurfaceView 的设计中引入了一个 子图层类型 的概念,用于定义这个独立的 Surface 相比较当前页面窗口 (即Activity) 的位置:

// /frameworks/base/core/java/android/view/SurfaceView.java
public class SurfaceView extends View {

// SurfaceView 的子图层类型
int mSubLayer = APPLICATION_MEDIA_SUBLAYER;

// SurfaceView 是否展示在当前窗口的最上方
// 该方法在挖洞和绘制流程中都有使用,最终影响到用户的视觉效果
private boolean isAboveParent() {

return mSubLayer >= 0;

}
}

// /frameworks/base/core/java/android/view/WindowManagerPolicyConstants.java
public interface WindowManagerPolicyConstants {
// ...
int APPLICATION_MEDIA_SUBLAYER = -2;
int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1;
int APPLICATION_PANEL_SUBLAYER = 1;
int APPLICATION_SUB_PANEL_SUBLAYER = 2;
int APPLICATION_ABOVE_SUB_PANEL_SUBLAYER = 3;
// ...
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
如代码所示,mSubLayer 默认值为 -2,这表示 SurfaceView 默认总是在 Activity 的下方,想要让 SurfaceView 展示在 Activity 上方,可以调用 setZOrderOnTop(true) 以修改 mSubLayer 的值:
————————————————

相关文章
|
编译器 API 容器
Compose:从重组谈谈页面性能优化思路,狠狠优化一笔
Compose:从重组谈谈页面性能优化思路,狠狠优化一笔
778 0
|
Android开发
Android 13 Qs面板的加载流程
Android 13 Qs面板的加载流程
1563 0
Android 13 Qs面板的加载流程
|
存储 Java 定位技术
gis利器之Gdal(二)shp数据读取
本文首先简单介绍了空间数据shp数据的基本知识,其常见的文件组成形式。使用qgis软件对数据进行常规预览,最后重点介绍了使用gdal对矢量信息进行读取,​包括空间信息和属性信息
1660 0
gis利器之Gdal(二)shp数据读取
|
5月前
|
JSON 自然语言处理 API
随机昵称姓名生成API:百亿级免费接口深度指南
接口盒子提供的“随机昵称姓名网名游戏名API”是一款强大名称生成工具,支持游戏ID、社交昵称等多场景应用。基于海量姓氏与词库,可生成百亿级不重复名称,具备高稳定性和完全免费特性,适用于各类开发需求。
404 0
|
自然语言处理 关系型数据库 MySQL
MySQL MATCH 匹配中文 无法查询的问题如何处理?
【8月更文挑战第29天】MySQL MATCH 匹配中文 无法查询的问题如何处理?
639 7
|
JavaScript 前端开发 安全
如何在 Vue 页面中禁止选择、右键、复制及 F12 开发者工具
【10月更文挑战第3天】 在前端开发中,保护页面内容不被随意复制或查看是一个常见需求。本文介绍了如何在 Vue 应用中实现禁止文本选择、右键菜单、复制操作以及 F12 开发者工具的方法。通过结合 CSS 和 JavaScript 事件监听,我们可以增加用户查看和复制内容的难度,尽管无法完全阻止高级用户。适当的防护措施可以为内容提供一层额外的保护,帮助开发者提升页面安全性。
1722 0
|
缓存 网络协议 编译器
针对Android系统工程师的C/C++学习目录
针对Android系统工程师的C/C++学习目录
270 0
|
Java Go Android开发
Android——编译(三):android.bp的相关知识
Android——编译(三):android.bp的相关知识
1675 0
|
存储 缓存 分布式数据库
[笔记]Windows核心编程《十七》内存映射文件(二)
[笔记]Windows核心编程《十七》内存映射文件(二)
541 0
|
XML Shell Linux
Windows下成功安装Repo和下载Android源码方法总结
Windows下成功安装Repo和下载Android源码方法总结