相关文章

  • SurfaceView、SurfaceHolder与Surface
  • TextureView、SurfaceTexture与Surface

按照官方文档的说法,SurfaceView继承自View,并提供了一个独立的绘图层,你可以完全控制这个绘图层,比如说设定它的大小,所以SurfaceView可以嵌入到View结构树中,但是需要注意的是,由于SurfaceView直接将绘图表层绘制到屏幕上,所以和普通的View不同的地方就在与它不能执行Transition,Rotation,Scale等转换,也不能进行Alpha透明度运算。SurfaceView的Surface排在Window的Surface(也就是View树所在的绘图层)的下面,SurfaceView嵌入到Window的View结构树中就好像在Window的Surface上强行打了个洞让自己显示到屏幕上,而且SurfaceView另起一个线程对自己的Surface进行刷新。特别需要注意的是SurfaceHolder.Callback的所有回调方法都是在主线程中回调的。

SurfaceView、SurfaceHolder、Surface的关系可以概括为以下几点:
* SurfaceView是拥有独立绘图层的特殊View
* Surface就是指SurfaceView所拥有的那个绘图层,其实它就是内存中的一段绘图缓冲区。
* SurfaceView中具有两个Surface,也就是我们所说的双缓冲机制
* SurfaceHolder顾名思义就是Surface的持有者,SurfaceView就是通过过SurfaceHolder来对Surface进行管理控制的。并且SurfaceView.getHolder方法可以获取SurfaceView相应的SurfaceHolder。
* Surface是在SurfaceView所在的Window可见的时候创建的。我们可以使用SurfaceHolder.addCallback方法来监听Surface的创建与销毁的事件。

下面我们写一个Demo来对普通的View与SurfaceView进行区别。

普通的View

我们先写一个继承自View的DrawView,我们每过1秒进行一次重绘

public class DrawView extends View {private static final int DELAY = 1000;private Paint mPaint;private int mCount;private Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {mCount++;invalidate();handler.sendEmptyMessageDelayed(0x0001, DELAY);}};public DrawView(Context context) {this(context, null);}public DrawView(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public DrawView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mPaint = new Paint();mPaint.setTextAlign(Paint.Align.CENTER);mPaint.setColor(0xFFFF0000);mPaint.setTextSize(50);}@Overrideprotected void onAttachedToWindow() {super.onAttachedToWindow();handler.sendEmptyMessageDelayed(0x0001, DELAY); //关联上Window后开始每1000ms重绘一次}@Overrideprotected void onDetachedFromWindow() {super.onDetachedFromWindow();handler.removeCallbacksAndMessages(null); //撤销关联时停止重绘,防止内存泄漏}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// 在View的中间绘制一个HelloWorld 并写上重绘的次数canvas.drawText("Hello World" + mCount, getWidth() >> 1, getHeight() >> 1, mPaint);}
}

然后我们把DrawView放到View结构树中

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextView
        android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:gravity="center"android:text="普通的View"android:textSize="20sp" /><cn.hufeifei.drawview.DrawView
        android:background="#ffffffff"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1" />
</LinearLayout>

为了能够看到DrawView刷新的情况,我们在开发者模式下打开显示surface更新的选项

执行结果

由于这里是使用gif录制的结果图,我特意将gif帧率调节到33FPS,才有这样的效果图。
我们可以看到每隔1秒界面就刷新了一次,显然这里刷新的是Window的surface。
**(使用模拟器的同学需要注意了,由于模拟器在显示到PC屏幕的过程中有延迟,模拟器在绘制时可能使用了双缓冲,所以模拟器显示出来的可能界面刷新的频率不一样)
**

SurfaceView的重绘

这次我们的DrawSurfaceView继承自SurfaceView

public class DrawSurfaceView extends SurfaceView implements SurfaceHolder.Callback {private static final long DELAY = 1000;private final SurfaceHolder mHolder;private Paint mPaint;private int mCount;private Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {mCount++;Canvas canvas = mHolder.lockCanvas();canvas.drawColor(0xFFFFFFFF);//擦除原来的内容canvas.drawText("Hello World" + mCount, getWidth() >> 1, getHeight() >> 1, mPaint);mHolder.unlockCanvasAndPost(canvas);sendEmptyMessageDelayed(0x0001, DELAY);}};public DrawSurfaceView(Context context) {this(context, null);}public DrawSurfaceView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public DrawSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mPaint = new Paint();mPaint.setTextAlign(Paint.Align.CENTER);mPaint.setColor(0xFFFF0000);mPaint.setTextSize(50);mHolder = getHolder();          //获取SurfaceView的ViewHolder对象mHolder.addCallback(this);    //为ViewHolder添加事件监听器}@Overridepublic void surfaceCreated(SurfaceHolder holder) {mHandler.sendEmptyMessageDelayed(0x0001, DELAY);Log.i("surfaceCreated", Thread.currentThread().getName());//打印当前线程的名字}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {Log.i("surfaceChanged", Thread.currentThread().getName());//打印当前线程的名字}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {mHandler.removeCallbacksAndMessages(null);Log.i("surfaceDestroyed", Thread.currentThread().getName());//打印当前线程的名字}
}

同样的我们把DrawSurfaceView放到View结构树中

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextView
        android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:gravity="center"android:text="SurfaceView"android:textSize="20sp" /><cn.hufeifei.drawview.DrawSurfaceView
        android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1" />
</LinearLayout>

可以看到很明显的区别,SurfaceView并没有刷新Window,而只是刷新了SurfaceView所在的界面区域,可以看出SurfaceView使用的是自己的surface。

从打印的log来看SurfaceHolder.Callback方法也确实是在主线程回调的。

实现代码点击这里

SurfaceView、SurfaceHolder与Surface相关推荐

  1. SurfaceView、GLSurfaceView、SurfaceTexture、TextureView、SurfaceHolder、Surface

    SurfaceView.GLSurfaceViewe\SurfaceTexture.TextureView.SurfaceHolder.Surface 一.简介 SurfaceTexture: Sur ...

  2. Surface SurfaceView SurfaceHolder

    Surface 查询Android SKD得到解释(Handle onto a raw buffer that is being managed by the screen compositor.) ...

  3. View,SurfaceView,SurfaceHolder

    View:对于绘画来说,最重要的步骤是重载 onDraw方法并且修改画布Canvas. SurfaceView:1,You can control the format of this surface ...

  4. 安卓自定义相机拍照功能全解(不调用系统相机)

    全栈工程师开发手册 (作者:栾鹏) 安卓教程全解 安卓实现一个相机的基本功能. 启动和释放相机 由于拍照功能一般需要实时预览,所以比较耗电,因此在窗口的恢复和暂停函数中需要启动和释放相机 privat ...

  5. Android中的Surface, SurfaceHolder, SurfaceHolder.Callback, SurfaceView

    传入一个surface,然后让openGL在surface上画图 window->view hierachy(DecorView是tree的root)->ViewRoot->Surf ...

  6. [Android] Surface、SurfaceHolder与SurfaceView

    其实相当于MVC结构的三者关系:M(Surface).V(SurfaceView).C(SurfaceHolder) 1.Surface Handle onto a raw buffer that i ...

  7. Surface、SurfaceView、SurfaceHolder及SurfaceHolder.Callback之间的关系

    转载请包含网址:http://blog.csdn.net/pathuang68/article/details/7351317 一.Surface Surface就是"表面"的意思 ...

  8. android surfaceholder的数据,Surface、SurfaceView、SurfaceHolder详解

    一.Surface Surface就是"表面"的意思.在SDK的文档中,对Surface的描述是这样的:"Handle onto a raw buffer that is ...

  9. surfacecontrol.java_简单说说JAVA层中Surface、SurfaceView、SurfaceHolder及SurfaceHolder.Callback之间的关系...

    1.Surface Surface extends Object implements Parcelable java.lang.Object android.view.Surface Class O ...

最新文章

  1. TensorFlow 2.2.0-rc0,这次更新让人惊奇!
  2. 遇见BUG(4)不要默认电平标准!
  3. GAE 随机获取实体
  4. Python 中,matplotlib绘图无法显示中文的问题
  5. 300 Longest Increasing Subsequence 最长上升子序列
  6. input限制输入字符
  7. 博客文件第二部分 Linux Shell高级编程技巧——第一章 深入讨论
  8. DEX VMP与ARM VMP
  9. Matlab 移动通信原理-扩频通信系统仿真实验(扩频通信系统的多用户数据传输、利用蒙特卡罗仿真方法对扩频增益进行性能仿真)
  10. win32com excel转pdf
  11. qlistview 自定义控件_qlistview使用自定义模型的复选框
  12. 微信小程序使用赞赏码功能
  13. VS 中增加文件后缀类型的支持: 设置cpp支持.tpp
  14. Python编程:判断字符串中是否包含中文
  15. 从头开始训练一个依存分析器
  16. ORB-SLAM3:单目+imu 详细代码解读
  17. 苹果体验店:鲜为人知的乔布斯的秘密
  18. 缤纷多彩的404页面(404.html)
  19. 从苏宁电器到卡巴斯基第05篇:我在佳木斯的日子(上)
  20. Centos(rocky,red Hat)搭建npt服务,采用阿里ntp时间,保证时间一致性时间

热门文章

  1. 读取手机序列号IMEI,SIM序列号IMSI方法
  2. [MATLAB]中meshgrid函数的用法与实践(学习笔记)
  3. Net5开发的视频监控管理系统
  4. 【后端】10进制与进制转换以及斐波那契数列第N位的JAVA小练习
  5. 【catkin】——如何导入一个catkin包的头文件和动态库
  6. OAuth使用教程(一):初识OAuth
  7. matlab矩阵乘法结果出错,为啥矩阵乘法显示矩阵乘法维度不正确?是什么原因?...
  8. js 对象不支持此属性或方法
  9. android lib 界面库,全开源C++ DirectUI 界面库SOUI 3.0更新
  10. dfa matlab代码,DFA 的代码表示