TextureView SurfaceView 简介 案例
| Markdown版本笔记 | 我的GitHub首页 | 我的博客 | 我的微信 | 我的邮箱 |
|---|---|---|---|---|
| MyAndroidBlogs | baiqiantao | baiqiantao | bqt20094 | baiqiantao@sina.com |
目录
TextureView 简介
官方文档
案例:使用TextureView和MediaPlayer播放视频
Activity
MediaPlayerManager
案例:使用TextureView和Camera预览拍照
TextureView 简介
Android普通窗口的视图绘制机制是一层一层的,任何一个子元素或者是局部的刷新都会导致整个视图结构全部重绘一次,因此效率相对较低。
视频或者opengl内容往往是显示在SurfaceView中的,SurfaceView的工作方式是:创建一个置于应用窗口之后的新窗口。因为SurfaceView窗口刷新的时候不需要重绘应用程序的窗口,所以这种方式的效率非常高。
但是SurfaceView也有一些非常不便的限制,因为SurfaceView的内容不在应用窗口上,所以不能使用平移、缩放、旋转等变换操作,也难以放在ListView或者ScrollView中,同样不能使用UI控件的一些特性,比如View.setAlpha()。
为了解决这个问题,Android 4.0 中引入了TextureView,与SurfaceView相比,TextureView并没有创建一个单独的 Surface 用来绘制,这使得它可以像一般的View一样执行一些变换操作,设置透明度等。
TextureView的使用非常简单,你唯一要做的就是获取用于渲染内容的SurfaceTexture。
Textureview必须在硬件加速开启的窗口中。
官方文档
Class Overview
A TextureView can be used to display a content stream. Such a content stream can for instance be a video or an OpenGL scene场景. The content stream can come from the application's process as well as a remote远程 process.
TextureView can only be used in a hardware accelerated硬件加速 window. When rendered in呈现在 software, TextureView will draw nothing.
Unlike SurfaceView, TextureView does not create a separate单独的 window but behaves as a regular像平常的 View. This key核心的 difference allows a TextureView to be moved, transformed, animated动画, etc. For instance, you can make a TextureView semi-translucent半透明 by calling myView.setAlpha(0.5f).
Using a TextureView is simple: all you need to do is get its SurfaceTexture. The SurfaceTexture can then be used to render展示 content. The following example demonstrates how to render the camera preview into a TextureView:
A TextureView's SurfaceTexture can be obtained获得 either by invoking引用 getSurfaceTexture() or by using a TextureView.SurfaceTextureListener. It is important to know that a SurfaceTexture is available only after the TextureView is attached to a window (and onAttachedToWindow() has been invoked.) It is therefore highly recommended推荐 you use a listener to be notified when the SurfaceTexture becomes available.
It is important to note that only one producer制片人 can use the TextureView. For instance, if you use a TextureView to display the camera preview, you cannot use lockCanvas() to draw onto the TextureView at the same time.
案例:使用TextureView和MediaPlayer播放视频
Activity
public class TextureViewTestActivity extends Activity implements TextureView.SurfaceTextureListener {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//取消状态栏
TextureView textureView = new TextureView(this);
textureView.setSurfaceTextureListener(this);
textureView.setRotation(45.0f);//可以像普通View一样使用平移、缩放、旋转等变换操作
textureView.setAlpha(0.5f);
setContentView(textureView);
}
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
Log.i("bqt", "onSurfaceTextureAvailable");// SurfaceTexture准备就绪
if (new Random().nextBoolean()) {
String path = "http://ozvd186ua.bkt.clouddn.com/douyin.mp4";
MediaPlayerManager.getInstance().playUrlMedia(new Surface(surface), path);
} else {
try {
MediaPlayerManager.getInstance().playAssetMedia(new Surface(surface), getAssets().openFd("douyin.mp4"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
Log.i("bqt", "onSurfaceTextureSizeChanged");// SurfaceTexture缓冲大小变化
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
Log.i("bqt", "onSurfaceTextureDestroyed");// SurfaceTexture即将被销毁
MediaPlayerManager.getInstance().stopMedia();
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
//Log.i("bqt", "onSurfaceTextureUpdated");// SurfaceTexture通过updateImage更新
}
}
MediaPlayerManager
public class MediaPlayerManager {
private MediaPlayer mPlayer;
private static MediaPlayerManager instance = new MediaPlayerManager();
private MediaPlayerManager() {//构造方法私有
}
public static MediaPlayerManager getInstance() {
return instance;
}
/**
* 播放网络或本地中的Media资源
*/
public void playUrlMedia(Surface surface, String mediaPath) {
try {
if (mPlayer == null) {
mPlayer = new MediaPlayer();
mPlayer.setDataSource(mediaPath);
} else {
if (mPlayer.isPlaying()) {
mPlayer.stop();
}
mPlayer.reset();
mPlayer.setDataSource(mediaPath);
}
mPlayer.setSurface(surface);
mPlayer.setVolume(0.5f, 0.5f);
mPlayer.setLooping(true);
mPlayer.prepareAsync();
mPlayer.setOnPreparedListener(MediaPlayer::start);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 播放Asset中的Media资源
*/
public void playAssetMedia(Surface surface, AssetFileDescriptor fileDescriptor) {
try {
if (mPlayer == null) {
mPlayer = new MediaPlayer();
mPlayer.setDataSource(fileDescriptor.getFileDescriptor(), fileDescriptor.getStartOffset(), fileDescriptor.getDeclaredLength());
} else {
if (mPlayer.isPlaying()) {
mPlayer.stop();
}
mPlayer.reset();
mPlayer.setDataSource(fileDescriptor.getFileDescriptor(), fileDescriptor.getStartOffset(), fileDescriptor.getDeclaredLength());
}
mPlayer.setSurface(surface);
mPlayer.setVolume(0.5f, 0.5f);
mPlayer.setLooping(true);
mPlayer.prepareAsync();
mPlayer.setOnPreparedListener(MediaPlayer::start);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 停止播放Media
*/
public void stopMedia() {
try {
if (mPlayer != null) {
if (mPlayer.isPlaying()) {
mPlayer.stop();
}
mPlayer.release();
mPlayer = null;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
案例:使用TextureView和Camera预览拍照
public class TextureViewTestActivity extends Activity implements TextureView.SurfaceTextureListener {
private Camera mCamera;//权限【android.permission.CAMERA】
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//取消状态栏
TextureView mTextureView = new TextureView(this);
mTextureView.setSurfaceTextureListener(this);
mTextureView.setRotation(45.0f);//可以像普通View一样使用平移、缩放、旋转等变换操作
mTextureView.setAlpha(0.5f);
setContentView(mTextureView);
}
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
Log.i("bqt", "onSurfaceTextureAvailable");// SurfaceTexture准备就绪
try {
mCamera = Camera.open();//如果提示【Fail to connect to camera service】很可能是没申请权限,或申请权限了单用户没有给你权限
mCamera.setPreviewTexture(surface);
mCamera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
Log.i("bqt", "onSurfaceTextureSizeChanged");// SurfaceTexture缓冲大小变化
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
Log.i("bqt", "onSurfaceTextureDestroyed");// SurfaceTexture即将被销毁
mCamera.stopPreview();
mCamera.release();
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
//Log.i("bqt", "onSurfaceTextureUpdated");// SurfaceTexture通过updateImage更新
}
}
2018-5-23
TextureView SurfaceView 简介 案例的更多相关文章
- ThreadLocal 简介 案例 源码分析 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- protobuf Protocol Buffers 简介 案例 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- 集合 enum 枚举 简介 案例 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- LruCache DiskLruCache 缓存 简介 案例 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- Android - TextureView, SurfaceView和GLSurfaceView 以及 SurfaceTexture
这几个概念比较绕, 又比较相近. 初看比较糊涂, 把握关键点就好. 关键字 View SurfaceViewGLSurfaceViewTextureView这三个后缀都是View, 所以这三个东西都是 ...
- Android 5.0(Lollipop)中的SurfaceTexture,TextureView, SurfaceView和GLSurfaceView
SurfaceView, GLSurfaceView, SurfaceTexture以及TextureView是Android当中名字比较绕,关系又比较密切的几个类.本文基于Android 5.0(L ...
- Javassist 字节码 简介 案例 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- TabLayout ViewPager Fragment 简介 案例 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- Android(java)学习笔记151: SurfaceView使用
1.SurfaceView简介 在一般的情况下,应用程序的View都是在相同的GUI线程(UI主线程)中绘制的.这个主应用程序线程同时也用来处理所有的用户交互(例如,按钮单击或者文本输入) ...
随机推荐
- 【优先队列+贪心】BZOJ1826-[JSOI2010]缓存交换
……啊开始颓了. [题目大意] 已知当前集合最大容量为m,n个询问.每次询问一个元素,如果集合中没有则需要加入该元素,如果集合已经满了则需要先删去集合中的某些元素再加入.问至少要加入几次元素? [思路 ...
- 【转】Asp.net实现URL重写
[概述] URL重写就是首先获得一个进入的URL请求然后把它重新写成网站可以处理的另一个URL的过程.重写URL是非常有用的一个功能,因为它可以让你提高搜索引擎阅读和索引你的网站的能力:而且在你改变了 ...
- django orm 优化
.markdown-body hr::after,.markdown-body::after{clear:both}.loopLine,.messageLine0{marker-end:"u ...
- Codeforces Round #272 (Div. 2) A. Dreamoon and Stairs 水题
A. Dreamoon and Stairs 题目连接: http://www.codeforces.com/contest/476/problem/A Description Dreamoon wa ...
- j.u.c系列(05)---之重入锁:ReentrantLock
写在前面 ReentrantLock,可重入锁,是一种递归无阻塞的同步机制.它可以等同于synchronized的使用,但是ReentrantLock提供了比synchronized更强大.灵活的锁机 ...
- TC SRM600 DIV2
开始补TC. 目前才补完SRM600的DIV2. 题目:http://community.topcoder.com/tc?module=ProblemArchive 250: 很水,不解释,直接搞. ...
- Go内置库模块 flag
import "flag" flag包实现了命令行参数的解析.每个参数认为一条记录,根据实际进行定义,到一个set集合.每条都有各自的状态参数. 在使用flag时正常流程: 1. ...
- SRM 449 DIV 1 总结(550p标记下,下次做)
今天的250p搞得有点久了,500p是个类似铺瓷砖的dp题,这样先占个坑,给个poj的这类题列表,下次刷完了回来做! POJ 相关DP列表 http://blog.csdn.net/jayye1994 ...
- [Winform]Media Player com组件应用中遇到的问题
摘要 最近一个项目中,需要用到在客户端全屏循环播放视频,当时考虑使用开源的播放器,但控制起来不方便,然后考虑既然都是windows系统,那么可以考虑使用微软自带的Media Player播放器.所以在 ...
- C/S模式与B/S
网络程序开发的两种计算模式--C/S模式与B/S模式.两种各有千秋,用于不同场合. C/S适用于专人使用,安全性要求较高的系统: B/S适用于交互性比较频繁的场合,容易被人们所接受,倍受用户和软件开发 ...