TextureView和SurfaceTexture之间的关系

本文深入探讨了Android中TextureView和SurfaceTexture的工作原理及应用。TextureView作为View的子类,其SurfaceTexture只有在执行完onAttachedToWindow后才变得有效。通过一个具体的代码示例,展示了如何在TextureViewActivity中实现SurfaceTextureListener接口,以处理相机预览的纹理更新。

1.TextureView和SurfaceTexture

(1)定义以及使用
public class TextureView extends View.
public class SurfaceTexture.
从android源码类的定义可以看出TextureView是一个view.当TextureView执行完onAttachedToWindow时,它的SurfaceTexture才是有效可用的.
所以SurfaceTextureListener接口用于让TextureView的使用着知道SurfaceTexture已经ready,这样可以把SurfaceTexture交给对应的内容源.
(2)形象功能
曾经在网上看到这样说:如果说TextureView是一幅画的话,那SurfaceTexture就是画布,真正渲染的载体是SurfaceTexture
那么我的理解是view是一个显示,是否可以说成,TextureView是一个呈现,可比作为黑板,SurfaceTexture就是黑板的表层用来承载流显示的一个载体.

2.代码演示

package com.example.textureviewactivity;
import java.io.IOException;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.TextureView;

public class TextureViewActivity extends Activity implements TextureView.SurfaceTextureListener{

private TextureView mTextureView;
private Camera mCamara;
private String tag = "TextureViewActivity";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mTextureView = new TextureView(this);
Log.d(tag,"after new TextureView,before set listener");
mTextureView.setSurfaceTextureListener(this);//设置监听
Log.d(tag,"after set listener");
setContentView(mTextureView);
}

public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height){
Log.d(tag,"onSurfaceTextureAvailable surface: "+surface);
mCamara = Camera.open();
try{
mCamara.setPreviewTexture(surface);
mCamara.startPreview();
}catch(IOException ioe){
}
}

public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height){
}

public boolean onSurfaceTextureDestroyed(SurfaceTexture surface){
Log.d(tag,"onSurfaceTextureDestroyed");
mCamara.stopPreview();
mCamara.release();
returntrue;
}

public void onSurfaceTextureUpdated(SurfaceTexture surface){
}

@Override
public void onPause(){
super.onPause();
Log.d(tag,"onPause");
}

@Override
public void onDestroy(){
super.onDestroy();
Log.d(tag,"onDestroy");
}

@Override
publicboolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
returntrue;
}

 

测试结果:

07-16 10:07:30.145 4672  4672 D TextureViewActivity: after new TextureView,before set listener
07-16 10:07:30.145 4672  4672 D TextureViewActivity: after set listener
//此处可以得出设置完监听后,且onAttachedToWindow后此处将会回调表明SurfaceTexture ready 有效.
07-16 10:07:30.250 4672  4672 D TextureViewActivity: onSurfaceTextureAvailable surface:android.graphics.SurfaceTexture@9f2b3ff
07-16 10:07:36.415 4672  4672 D TextureViewActivity: onPause
07-16 10:07:36.545 4672  4672 D TextureViewActivity: onSurfaceTextureDestroyed
07-16 10:07:36.897 4672  4672 D TextureViewActivity: onDestroy

 对应camera的使用权限可以在配置文件添加进去,此处不做过多说明.

 

转载于:https://www.cnblogs.com/syyh2006/p/9318224.html

<think>嗯,用户的问题是关于Android中TextureView/SurfaceTexture与SurfaceView在流程上的区别。用户特别强调了"流程区别",说明ta需要的是工作机制层面的对比,而不是简单的特性列表。 用户可能正在做图形渲染相关的开发,遇到了性能问题需要选型。从ta引用的资料看,已经查阅了官方文档但仍有困惑,需要更落地的流程分析。这类问题通常出现在视频播放器、相机预览或游戏开发场景中。 我注意到用户引用了三条资料:第一条讲TextureView的渲染流程依赖SurfaceTextureSurface;第二条对比两者适用场景;第三条提到SurfaceTexture的监听机制线程限制。这些正好覆盖了流程对比的三个关键维度:初始化、渲染路径线程模型。 需要重点解析的差异点包括: 1) SurfaceView直接使用独立Surface绕过View体系,而TextureView通过SurfaceTexture桥接 2) SurfaceView的挖洞机制(WMS合成) vs TextureView的OpenGL纹理转换 3) 5.0前后TextureView线程模型变化对流程的影响 特别要注意用户上次提问时提到"流程上的区别",所以回复要严格按时间线展开: - 初始化阶段:SurfaceView直接连接SurfaceHolder,TextureView需要等待SurfaceTextureReady - 数据流动阶段:SurfaceView直接推数据到Surface,TextureView多一步GPU纹理转换 - 合成阶段:WMS合成 vs View系统合成 用户可能没意识到的潜在问题:当提到"TextureView必须在硬件加速窗口"时,需要解释为什么5.0前在主线程渲染——因为早期版本没有单独的GL线程,这个细节会影响卡顿分析。 最后生成的问题要引导用户思考具体场景:如果ta正在开发相机应用,SurfaceView的低延迟更重要;如果是视频滤镜应用,则TextureView的动画支持更合适。三个衍生问题分别对应原理深度(渲染管线)、实践陷阱(线程泄露)设计决策(选型依据)。</think>以下是Android中TextureView/SurfaceTexture与SurfaceView在**工作流程**上的核心区别分析,结合关键步骤对比: --- ### **一、SurfaceView 工作流程** 1. **创建独立Surface** SurfaceView会向`WindowManagerService`申请**独立于应用窗口的Surface层**(默认位于主窗口下方),通过`SurfaceHolder`接口管理[^2]。 2. **渲染分离** - 在**独立渲染线程**(非主线程)中绘制内容到Surface - 通过`lockCanvas()`获取Canvas,绘制完成后`unlockCanvasAndPost()`提交[^1] 3. **窗口合成(WMS)** `WindowManagerService`直接将Surface内容合成到屏幕,**跳过应用View树的绘制流程**("挖洞"效果)[^3]。 ```mermaid graph LR A[SurfaceView初始化] --> B[WMS分配新Surface] B --> C[应用在独立线程绘制] C --> D[WMS直接合成到屏幕] ``` --- ### **二、TextureView/SurfaceTexture 工作流程** 1. **SurfaceTexture初始化** - 创建`SurfaceTexture`对象(关联OpenGL纹理ID) - 绑定到`TextureView`的`SurfaceTextureListener`[^3] 2. **Surface桥接** - 通过`SurfaceTexture`创建`Surface`对象 - 内容生产者(如Camera/MediaPlayer)将图像流写入此`Surface`[^1] 3. **GPU纹理转换** `SurfaceTexture`将图像流转换为**OpenGL纹理**,通过`updateTexImage()`更新纹理帧[^3] 4. **View系统合成** TextureView作为常规View,通过**硬件加速渲染**将纹理绘制到应用View树中,参与标准测量/布局流程[^2]。 ```mermaid graph LR A[TextureView初始化] --> B[创建SurfaceTexture] B --> C[生产者写入Surface] C --> D[SurfaceTexture转OpenGL纹理] D --> E[TextureView通过GPU合成到View树] ``` --- ### **三、关键流程差异对比** | **特性** | **SurfaceView** | **TextureView** | |------------------------|----------------------------------|-------------------------------------| | **渲染层级** | WMS直接管理独立图层 | 应用View树的一部分 | | **合成方式** | 由WMS硬件合成 | 通过View系统硬件加速合成 | | **线程模型** | 强制独立渲染线程 | 5.0前在主线程,5.0后独立渲染线程[^3] | | **动画支持** | 不支持缩放/旋转等动画 | 支持完整动画 | | **性能开销** | 内存更低,延迟更小 | 额外纹理转换开销,内存更高[^3] | | **内容更新机制** | 直接控制Canvas绘制 | 监听`onFrameAvailable()`更新纹理 | --- ### **四、典型应用场景** - **SurfaceView适用**: 视频播放器(低延迟)、相机预览(高性能)、游戏渲染 - **TextureView适用**: 需要动画的播放器(如旋转/缩放)、动态滤镜、小窗播放(与View树交互) > ⚠️ 注意:TextureView在5.0以下版本因在主线程渲染可能导致卡顿,且必须开启硬件加速[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值