Android SurfaceView基础用法详解

Android 游戏开发框架核心组件

核心组件介绍

SurfaceView 介绍

  1. SurfaceView 介绍 SurfaceView 就是带 Surface 的 view,它是一个 View,是 View 的子类,所以和其他 View 一样,可以在屏幕上展示东西接收用户输入,具有 View 的生命周期回调函数,如 onMeasure、onLayout、onDraw、onTouchEvent 等
  2. SurfaceView 带有独立的 Surface(独立与 window 的 surface),这可以让子线程在独立的 Surface 上面绘制东西,进行 SurfaceView 的界面绘制,这个子线程就叫做渲染线程,但是要让独立的 Surface 上面的东西在 View 上面展示出来,需要 post 一个消息给主线程,目的是把该 Surface 中 canvas 上的东西绘制到 View 的真正的画布上面(window 的 surface 的 canvas上),这样就可以把 UI 线程空闲出来处理用户的交互
  3. Surface 可能被销毁,它只在SurfaceHolder.Callback.surfaceCreated() 和 SurfaceHolder.Callback.surfaceDestroyed() 之间有效,这只是说 Surface 创建和销毁的时候会回到前面两个方法,所以要确保渲染线程访问的是合法有效的 surface
  4. SurfaceHolder.CallBack 是通过 SurfaceView 的 SurfaceHolder 的 addCallback 来设置给 SurfaceHolder 的,让 SurfaceView 实现 CallBack 并设置给 SurfaceHolder,SurfaceView 就可以监听这个独立 Surface 的创建和销毁了。

sdk 中的介绍

SurfaceView是视图(View)的继承类,这个视图里内嵌了一个专门用于绘制的Surface。你可以控制这个Surface的格式和尺寸。Surfaceview控制这个Surface的绘制位置。
surface是纵深排序(Z-ordered)的,这表明它总在自己所在窗口的后面。surfaceview提供了一个可见区域,只有在这个可见区域内 surface 部分内容才可见,可见区域外的部分不可见。
surface 的排版显示受到视图层级关系的影响,它的兄弟视图结点会在顶端显示。这意味者 surface
的内容会被它的兄弟视图遮挡,这一特性可以用来放置遮盖物(overlays)(例如,文本和按钮等控件)。注意,如果 surface 上面有透明控件,那么它的每次变化都会引起框架重新计算它和顶层控件之间的透明效果,这会影响性能。
你可以通过 surfaceHolder 接口访问这个surface,getHolder() 方法可以得到这个接口。
surfaceview 变得可见时,surface被创建;surfaceview隐藏前,surface被销毁。这样能节省资源。如果你要查看 surface 被创建和销毁的时机,可以重载surfaceCreated(SurfaceHolder)和 surfaceDestroyed(SurfaceHolder) surfaceView 的核心在于提供了两个线程:UI线程和渲染线程。
这里应注意:
1. 所有 SurfaceView 和 SurfaceHolder.Callback 的方法都会在UI线程里调用,一般来说就是应用程序主线程。所以渲染线程所要访问的各种变量应该作同步处理。
2. 由于surface可能被销毁,它只在SurfaceHolder.Callback.surfaceCreated()和 SurfaceHolder.Callback.surfaceDestroyed()之间有效,所以要确保渲染线程访问的是合法有效的
surface。

SurfaceHolder 介绍

SurfaceHolder 是对 SurfaceView 的 Surface 的包装,不但在 SurfaceHolder.callback 接口中负责 Surface 创建和销毁的回调,而且还对 Surface 的关键方法 LockCanvas()、unLockCanvasAndPost() 方法进行了线程安全的包装,所以 SurfaceHolder 是 Surface 对象的持有者,负责 Surface 的生命周期中的对 Surface 操作的方法的调用
脏矩形 Rect dirty,是指标记这块矩形区域的数据作废,也就是需要重写绘制的矩形区域,LockCanvas(Rect dirty),可以指定一个矩形区域,让 Surface 中的 Canvas 上部分数据重绘。

SurfaceView、SurfaceHolder、Surface 之间的关系

SurfaceView 使用的步骤

  1. 获取到 SurfaceView 对应的 SurfaceHolder,给 SurfaceHolder 添加一个 SurfaceHolder.callback 对象。
  2. 创建渲染线程对象
  3. 在子线程中开始在 Surface 上面绘制图形,因为SurfaceView没有对我们暴露 Surface,而只是暴露了 Surface 的包装器 SurfaceHolder,所以使用 SurfaceHolder 的 lockCanvas()获取 Surface 上面指定区域的 Canvas,在该 Canvas 上绘制图形,绘制结束后,使用 SurfaceHolder 的 unlockCanvasAndPost()方法解锁 Canvas,并且让 UI 线程把 Surface 上面的东西绘制到 View 的 Canvas 上面

SurfaceView 使用的 demo

public class GameUI extends SurfaceView implements SurfaceHolder.Callback {

    private SurfaceHolder holder;
    private RenderThread renderThread;
    private boolean isDraw = false;// 控制绘制的开关

    public GameUI(Context context) {
        super(context);
        holder = this.getHolder();
        holder.addCallback(this);

        renderThread = new RenderThread();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        isDraw = true;
        renderThread.start();

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        isDraw = false;

    }

    /**
    * 绘制界面的线程
    *
    * @author Administrator
    *
    */
    private class RenderThread extends Thread {
        @Override
        public void run() {
            // 不停绘制界面
            while (isDraw) {
                drawUI();
            }
            super.run();
        }
    }

    /**
    * 界面绘制
    */
    public void drawUI() {
        Canvas canvas = holder.lockCanvas();
        try {
            drawCanvas(canvas);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            holder.unlockCanvasAndPost(canvas);
        }
    }

    private void drawCanvas(Canvas canvas) {
        // 在 canvas 上绘制需要的图形
    }
}

到此这篇关于Android SurfaceView基础用法详解的文章就介绍到这了,更多相关Android SurfaceView基础内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android截屏SurfaceView黑屏问题的解决办法

    最近项目中有截屏的需求,普通的view截屏方法网上一搜一大把,但是SurfaceView截屏黑屏问题很多文章说的并不清楚,自己参考了一些别的博客,再加上自己的思考,算是找到了一种解决方案. 1.首先看我们一般是怎么用SurfaceView的 public class SuperSurfaceView extends SurfaceView implements SurfaceHolder.Callback { SurfaceHolder surfaceHolder; public SuperSu

  • Android利用SurfaceView实现下雨的天气动画效果

    首先是最终实现的效果图: 先分析一下雨滴的实现: 每个雨滴其实就是一条线,通过 canvas.drawLine() 绘制 线(雨滴)的长度.宽度.下落速度.透明度以及位置都是在一定范围内随机生成 每 draw 一次然后改变雨滴的位置然后重绘即可实现雨滴的下落效果 分析完了,那么可以直接写一个类直接继承 View ,然后重写 onDraw() 吗?可以看到效果图中的雨滴的下落速度很快,那么意味着每一帧都要调用 onDraw() 一次使其重新绘制一次,假如你的 onDraw() 方法里面的渲染代码稍

  • Android利用SurfaceView实现简单计时器

    自学了android有几个月了,跟着网上的节奏,应该早点写些博客来提高自己的水准的.但苦于技术水准始终不自信(也是不过关的结果吧),就一直只是将自己学习过程中的问题和重要的知识点写在自己的笔记文档中. 但,总感觉一个人写下来成就感还是欠缺了那么一些,而且有些问题及解答方法抛出来,是有可能得到更多好的反馈及解决方案的.于是,本着不作不会死的心态,一步一步在技术成长的道路前行-->这篇博客就是其中一步! 若博客中有些技术知识点有误或者有更优化的解答方案,还望各位小伙伴多多指出. 以下是正题了: 目标

  • Android切换至SurfaceView时闪屏(黑屏闪一下)以及黑屏移动问题的解决方法

    1.最近的项目中,有一个Activity用到Fragment+ViewPager,其中一个fragment中实现了视频播放的功能,包含有SurfaceView.结果,每次打开程序第一次进入到该Activity时都会闪屏黑一下.原因就出在SurfaceView. 详解: I think I found the reason for the black flash. In my case I'm using a SurfaceView inside a Fragment and dynamicall

  • Android Surfaceview的绘制与应用

    Android  Surfaceview的绘制与应用 一.surfaceview与view的区别 Android 提供了view进行视图的绘制,可以满足大部分的会图需求,但在有些时候却是心有余而力不足.我们知道,view通过刷新来绘制视图.android系统通过vsync信号来进行屏幕的绘制.刷新的时间间隔为16毫秒.如果在16毫秒内完成了索要刷新的绘制操作,那么在视觉效果上就不会产生卡顿的感觉.如果逻辑操作过多,频繁刷新就会造成界面的卡顿. 对于这一问题,Android提供了surfacevi

  • Android使用SurfaceView实现飘赞动画

    最近做直播项目,需要实现点赞动画,一提起动画就想到了使用View的属性动画,后来想了一下,那么多用户点赞,会导致屏幕上出现很多View,开销太大,一定会很卡,所以看主流主播软件用什么方案解决的. 于是反编译了映客apk,大概看了一下,它的点赞只用了一个SurfaceView,每个心都是实时画到画布上去的,这样效率确实很高,再多的心也不怕了.思路有了,但是自己从头到尾写毕竟麻烦,后来上网查了是否有其他人已经做好了呢?果然有现成的,思路很清晰,很简洁,根据自己的需求改一改就好了. 前面说了一堆,主要

  • android使用surfaceview+MediaPlayer播放视频

    Android中播放视频主要有两种方式: 使用其自带的播放器.指定Action为ACTION_VIEW,Data为Uri,Type为其MIME类型 使用android自带的VideoView,这种方法太简单就不介绍了 使用SurfaceView+MediaPlayer,这种方式效果比较好,这里也重点介绍 SurfaceView从android 1.0就有了,十分好用.一般来说,UI对刷新都需要在UI线程中完成,但是,surfaceview可以在非UI线程中完成刷新.这样以来就很方便了,比如在线播

  • Android SurfaceView基础用法详解

    Android 游戏开发框架核心组件 核心组件介绍 SurfaceView 介绍 SurfaceView 介绍 SurfaceView 就是带 Surface 的 view,它是一个 View,是 View 的子类,所以和其他 View 一样,可以在屏幕上展示东西接收用户输入,具有 View 的生命周期回调函数,如 onMeasure.onLayout.onDraw.onTouchEvent 等 SurfaceView 带有独立的 Surface(独立与 window 的 surface),这可

  • vuex state及mapState的基础用法详解

    先使用vue cli构建一个自己的vue项目 1.npm i -g vue-cli 2.vue init webpack sell (sell是你的项目名) 3.一路回车(在这个过程中会提示你是否安装一些依赖包,比如vue-router,es6语法检查等等,这些根据你个人习惯或者癖好选择Y/N) 4.npm i (这个是安装项目的依赖包) 5.npm run dev(启动你的vue项目) 这个时候如果在页面上看到了vue的logo说明你的vue的项目基础构建已经完成,然后你可以删除掉没有用的组件

  • Python写脚本常用模块OS基础用法详解

    收集了一些关于OS库的用法,整理归纳一下,方便使用 import os # 系统操作 print(os.sep) # 获取当前系统的路径分隔符 print(os.name) # 获取当前使用的工作平台 print(os.getenv('PATH')) # 获取名为 PATH 的环境变量 print(os.getcwd()) # 获取当前的路径 print(os.environ['PATH']) # 可以返回环境相关的信息 不传参时,以字典的方式返回所有环境变量 # 调用系统命令 os.syste

  • Android WebView基础应用详解

    目录 一.WebView的基础配置 二.WebView支持播放音乐 三.WebView支持视频播放 四.WebChromeClient 五.WebViewClient 1.重定向问题 2.实现预加载 3.增加错误页面展示限制 4.解决页面白屏问题 附GitHub源码:WebViewExplore 一.WebView的基础配置 WebSettings ws = getSettings(); ws.setBuiltInZoomControls(true);// 隐藏缩放按钮 ws.setLayout

  • Android SQLite基本用法详解

    目录 一.SQLite的介绍 1.SQLite简介 2.SQLite的特点: 3.SQLite数据类型 二.SQLiteDatabase的介绍 1.打开或者创建数据库 2.创建表 3.插入数据 4.删除数据 5.修改数据 6.查询数据 7.删除指定表 三. SQLiteOpenHelper 1.onCreate(SQLiteDatabase) 2.  onUpgrade(SQLiteDatabase,int,int)  3.  onOpen(SQLiteDatabase): 一.SQLite的介

  • Android ContentProvider基础应用详解

    目录 一.适用场景 二.概念介绍 1.ContentProvider简介 2.Uri类简介 三.使用步骤 1.首先创建一个继承自ContentProvider的类,并实现其6个方法: 2.在Manifest文件中注册这个ContentProvider: 3.在外部应用中访问它: 一.适用场景 1.ContentProvider为存储和读取数据提供了统一的接口 2. 使用ContentProvider,应用程序可以实现数据共享 3. android内置的许多数据都是使用ContentProvide

  • Android之Spinner用法详解

    目录 一.Spinner的两种展示样式 二.Spinner相关方法 三.Spinner用法举例 XML布局文件activity_main.xml 选中文字样式item_select.xml 列表其他文字样式item_dropdown.xml Java代码MainActivity.java 四.dropdown模式下的列表分割线 一.Spinner的两种展示样式 下拉列表的展示方式有两种,一种是在当前下拉框的正下方展示列表,此时把spinnerMode属性设置为dropdown;另一种是在页面中部

  • Java BigDecimal基础用法详解

    目录 一.BigDecimal概述 二.BigDecimal常用构造函数 2.1.常用构造函数 2.2.使用问题分析 三.BigDecimal常用方法详解 3.1.常用方法 3.2.BigDecimal大小比较 四.BigDecimal格式化 五.BigDecimal常见异常 5.1.除法的时候出现异常 六.BigDecimal总结 6.1.总结 6.2.工具类推荐 一.BigDecimal概述 一般情况下,对于那些不需要准确计算精度的数字,我们可以直接使用Float和Double处理,但是Do

  • Android RecyclerView 基础知识详解

    本周的谷歌I/O大会带来了很多关于Android的振奋人心的消息.可能我们需要较长的时间来消化Android L引入的新东西. 这些天我一直在研究RecyclerView,并想在此给各位分享一下到目前为止我的成果. RecyclerView是什么? RecyclerView是一种新的视图组,目标是为任何基于适配器的视图提供相似的渲染方式.它被作为ListView和GridView控件的继承者,在最新的support-V7版本中提供支持. 在开发RecyclerView时充分考虑了扩展性,因此用它

  • Android SharedPreferences存储用法详解

    先看Demo运行效果 SharedPreferences详解 SharedPreferences是Android平台上一个轻量级的存储类,用来保存应用的一些常用配置,比如Activity状态,Activity暂停时,将此activity的状态保存到SharedPereferences中:当Activity重载,系统回调方法onSaveInstanceState时,再从SharedPreferences中将值取出. SharedPreferences提供了java常规的Long.Int.Strin

随机推荐