Android的Surface、View、SurfaceView、Window概念整理

转载自:http://www.360doc.com/content/19/0927/10/8335678_863480139.shtml

最近了解了一下Android中几个关于视图的概念:Surface、View、SurfaceView与Window,在此进行一下总结整理

BufferQueue

在此之前,我们先介绍一下BufferQueue。
BufferQueue类是 Android 中所有图形处理操作的核心。它的作用很简单:将生成图形数据缓冲区的一方(生产方)连接到接受数据以进行显示或进一步处理的一方(消耗方)。几乎所有在系统中移动图形数据缓冲区的内容都依赖于BufferQueue。
简而言之,BufferQueue是图形生产者消费者模型中沟通的桥梁。
它的基本用法很简单:生产方请求一个可用的缓冲区 (dequeueBuffer()),并指定一组特性,包括宽度、高度、像素格式和用法标记。生产方填充缓冲区并将其返回到队列 (queueBuffer())。随后,消耗方获取该缓冲区 (acquireBuffer()) 并使用该缓冲区的内容。当消耗方操作完毕后,将该缓冲区返回到队列 (releaseBuffer())。

更详细介绍可参考官方文档:
https://source.android.com/devices/graphics/arch-bq-gralloc

SurfaceFlinger

在介绍Surface之前,我们还需要先了解一下SurfaceFlinger。
SurfaceFlinger的作用是接受来自多个来源的数据缓冲区,对它们进行合成,然后发送到显示设备。
当别的服务向SurfaceFlinger请求一个绘图Surface时,它会创建一个主要组件是BufferQueue的新的层(这里的层博主感觉指的是一层层的视图的意思),同时把自己设定为消耗方。大多数应用通常在屏幕上有三个层:屏幕顶部的状态栏、底部或侧面的导航栏以及应用的界面。

更详细介绍可参考官方文档:
https://source.android.com/devices/graphics/arch-sf-hwc

Surface

从 1.0 开始,Surface类一直是公共 API 的一部分。它的描述简单如下:“在由屏幕合成器管理的原始缓冲区上进行处理”。
Surface表示通常(但并非总是!)由SurfaceFlinger消耗的缓冲区队列的生产方。当您渲染到Surface上时,产生的结果将进入相关缓冲区,该缓冲区被传递给消耗方。
简单来说,博主认为我们可以把Surface当做是一层视图,我们通过在Surface上绘制图像,来往其中的BufferQueue生产视图数据,进而交给其消耗方SurfaceFlinger来与其他视图层合成,最终显示到屏幕上。

更详细介绍可参考官方文档:
https://source.android.com/devices/graphics/arch-sh
https://developer.android.com/reference/android/view/Surface

Window

Window类代表着一个视图的顶层窗口,它管理着这个视图中最顶层的View,提供了一些背景、标题栏、默认按键等标准的UI处理策略。
同时,它拥有唯一一个用以绘制自己的内容的Surface,当app通过WindowManager创建一个Window时,WindowManager会为每一个Window创建一个Surface,并把该Surface传递给app以便应用在上面绘制内容。
博主认为Window与Surface之前存在着一对一的关系。

更详细介绍可参考官方文档:
https://developer.android.com/reference/android/view/Window

View

View这个类相信大家都普遍比较熟悉,它是Android视图中的一个基本单位。
它代表着屏幕上的一个矩形区域,并负责绘制该区域以及处理区域上的点击事件。
它与ViewGroup通过组合设计模式,共同组成了Android视图的基石,通过最顶层的ViewRootImpl我们可以一层层遍历View组成的树状结构。
最顶层的View会由某个Window进行打理,在对其复杂的层级结构进行测量、布局、绘制后,其中的所有内容最终会绘制到Window拥有的Surface中去。

更详细介绍可参考官方文档:
https://developer.android.com/reference/android/view/View

SurfaceView

SurfaceView是一种被特殊实现的View,它拥有自己专门的一个Surface,以便让应用直接在里面绘制内容。
它能与普通的View一样,在View组成的树状结构中进行测量与布局,但却独立于普通View所共享Window的那个Surface。它在需要渲染时,内容会变得完全透明,SurfaceView的View部分只是一个透明的占位符。
SurfaceView的工作原理如下,它所做的全部就是要求WindowManager创建一个Window,并告诉WindowManager所创建的Window的Z轴顺序(Z-order),这个Z轴顺序可以帮助WindowManager决定将新建的window置于SurfaceView所属Window的前面还是后面。
然后,WindowManager会将新建的Window放置到SurfaceView在所属Window中的位置。如果新建Window在SurfaceView所属Window后面,SurfaceView会将它在所属Window中占据的部分变透明,以便让后面的Window显示出来。

要在Android上动态添加SurfaceView,您需要执行以下步骤: 1. 创建一个自定义视图类,继承SurfaceView并实现相关的方法。 2. 在您的活动或片段中创建一个视图组,例如LinearLayout,以用于容纳SurfaceView。 3. 在您的活动或片段中实例化自定义视图类,并将其添加到视图组中。 以下是一个简单的示例代码,演示如何动态添加SurfaceView到LinearLayout中: ``` public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder holder; public MySurfaceView(Context context) { super(context); holder = getHolder(); holder.addCallback(this); } @Override public void surfaceCreated(SurfaceHolder holder) { // 初始化绘制线程等相关操作 } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // 视图大小发生改变时的处理 } @Override public void surfaceDestroyed(SurfaceHolder holder) { // 停止绘制线程等相关操作 } } public class MainActivity extends AppCompatActivity { private LinearLayout layout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); layout = findViewById(R.id.surface_container); MySurfaceView surfaceView = new MySurfaceView(this); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT); layout.addView(surfaceView, params); } } ``` 在上面的示例中,MySurfaceView类继承了SurfaceView并实现了SurfaceHolder.Callback接口,以便在创建、大小更改和销毁SurfaceView时执行适当的操作。MainActivity类包含一个LinearLayout视图组,它具有一个ID为surface_container的布局元素。在onCreate方法中,我们实例化MySurfaceView类,并将其添加到LinearLayout视图组中。 请注意,您可以使用不同的布局元素和布局参数来容纳SurfaceView。此外,您可以根据需要对MySurfaceView类进行自定义,以实现您的特定需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值