Surfaceview简介
1.什么是Surfaceview?
SurfaceView是视图(View)的继承类,这个视图里内嵌了一个专门用于绘制的surface。我们可以控制这个surface的格式和尺寸。SurfaceView控制这个surface绘制的位置。surface类直接继承Object,对应了一块屏幕缓冲区,每个窗口window对应一个Surface,任何View都是画在Surface上的,传统的view共享一块屏幕缓冲区。
2.Surfaceview的特点
首先,我们先来查看官方API对SurfaceView的介绍,如图1-1所示:
图1-1
Surfaceview的特性:内部维护了两个线程即主线程和渲染线程,渲染线程可以在主线程之外的线程中向屏幕上绘图。这样可以避免主线程因绘图任务繁重导致程序的阻塞,从而提高了程序的反应速度。在游戏开发中多用surfaceView,游戏的背景,任务,动作尽量在画布Canvas中绘制。这种双线程的设计模式,极大的消耗了CPU内存,为此,SurfaceView可见时才被创建,SurfaceView隐藏时便被销毁,从而达到节约内存的目的。
3.Surfaceview的用法
在项目中,我们常常会编写自己的SurfaceView,很少使用原生态的SurfaceView。不过这两种使用方法的内部原理是一样的。下面我们就使用原生态SurfaceView的过程做如下阐述:
1.创建SurfaceView对象
2.调用SurfaceView的getHolder方法,得到SurfaceView的控制器
3.SurfaceHolder添加回调函数,重写该回调函数的onCreate方法和onDestroy方法。
4.SurfaceView只在surfaceCreated和surfaceDestroyed之间有效,所以要确保渲染线程访问的是合法有效的Surface。
但是我们在实际操作SurfaceView的时候,总会遇到空指针的问题,并且不好找问题出在哪,在下面我会总结了几个常见的会报空指针的情况,给大家参考下。
熟悉Android的工程师都知道,在主线程中不可以做耗时操作,在子线程中不能更新UI,那么我们先做一个小例子来看看SurfaceView是否能在子线程更新UI呢?
首先打开Studio
首先打开Studio
一、设计布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.zhiyuan3g.surfaceviewdemo.MainActivity">
<SurfaceView
android:id="@+id/sv_surfaceView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开启子线程更新UI"
android:id="@+id/btnOK"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
二、在MainActivity的Button按钮点击事件中,我们做一个在子线程中画圆的操作来展示在子线程中UI确实被更新了,在这面我们用到的是一个画圆的操作,每一次因为圆的半径在累加,所以能直观的看出效果,我还在注释中解释了MVC模式,画布,画笔,上色等,相信只要有安卓基础的人按照注释来就没有问题,下面代码中每一步都有注释,解释的十分明白(注意:必须有释放画布的操作)。
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnOK: