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主线程)中绘制的.这个主应用程序线程同时也用来处理所有的用户交互(例如,按钮单击或者文本输入) ... 
随机推荐
- BZOJ.4517.[SDOI2016]排列计数(错位排列 逆元)
			题目链接 错位排列\(D_n=(n-1)*(D_{n-1}+D_{n-2})\),表示\(n\)个数都不在其下标位置上的排列数. 那么题目要求的就是\(C_n^m*D_{n-m}\). 阶乘分母部分的 ... 
- zoj 3659 第37届ACM/ICPC 长春赛区现场赛E题 (并查集)
			题意:给出一棵树,找出一个点,求出所有点到这个点的权值和最大,权值为路径上所有边权的最小值. 用神奇的并查集,把路按照权值从大到小排序,然后用类似Kruskal的方法不断的加入边. 对于要加入的一条路 ... 
- Xtreme9.0 - Taco Stand 数学
			Taco Stand 题目连接: https://www.hackerrank.com/contests/ieeextreme-challenges/challenges/taco-stand Des ... 
- oracle切割以,隔开的数字字符串
			提前声明strsplit_typeCREATE OR REPLACE TYPE strsplit_type as table of varchar2(4000); 如果不,会报错:PLS-00201: ... 
- Oracle初始化参数之memory_target
			一.引言: Oracle 9i引入pga_aggregate_target,可以自动对PGA进行调整: Oracle 10g引入sga_target,可以自动对SGA进行调整: Oracle 11g则 ... 
- VC设置代理方法
			参考文章: VC 设置代理 Setting and Retrieving Internet Options Change Internet Proxy settings http://suppor ... 
- 用Qemu搭建x86_64学习环境
			作者信息 作者:彭东林 邮箱:pengdonglin137@163.com QQ:405728433 软件平台 主机: Ubuntu14.04 64位版本 模拟器:Qemu-2.8.0 Linux内核 ... 
- X.509 数字证书结构和实例
			http://www.cppblog.com/sleepwom/archive/2010/07/08/119746.html 一. X.509数字证书的编码 X.509证书的结构是用ASN1(Abst ... 
- 利用npm 安装删除模块
			转自 涵一原文 利用npm 安装删除模块 1. npm安装模块 [npm install xxx]利用 npm 安装xxx模块到当前命令行所在目录:[npm install -g xxx]利用npm安 ... 
- UITableView分割线样式与颜色
			tv.separatorStyle = UITableViewCellSeparatorStyleSingleLine; //设置样式 tv.separatorColor = [UIColor c ... 
