当前位置: 首页 > news >正文

WMS:SurfaceView绘制显示

WMS:SurfaceView绘制显示

  • 1、SurfaceView控件使用
    • 1.1 Choreographer接受VSync信号
    • 1.2 自定义SurfaceView
    • 1.3 结果
  • 2、SurfaceView获取画布并显示
    • 2.1 SurfaceHolder.lockCanvas()
    • 2.2 SurfaceHolder.unlockCanvasAndPost(Canvas canvas)


1、SurfaceView控件使用

1.1 Choreographer接受VSync信号

Choreographer是Android提供的一个获取VSync信号的通道。这里SurfaceView控件是主动上屏绘制,而一般应用如
WMS中Choreographer 配合 VSYNC 中断信号 中添加界面时从 ViewRootImpl 的 scheduleTraversals 方法开始,其内部通过 Choreographer 的 postCallback 将绘制任务添加到 Chorographer。

Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() {@Overridepublic void doFrame(long frameTimeNanos) {//当vsync信号来时会调用到这里mHandler.sendEmptyMessage(MyHandler.TAG_UPDATE_TEXT);Choreographer.getInstance().removeFrameCallback(this);Choreographer.getInstance().postFrameCallback(this);}});

1.2 自定义SurfaceView

  • MySurfaceView构造函数中获取mSurfaceHolder = this.getHolder(),并设置SurfaceHolder.Callback
  • 继承RunnableThread中运行,并Global.syncCondition.await(); 在这里等待vsync到来的通知消息
  • 线程并发处理LockCondition
public class Global {public static ReentrantLock lock = new ReentrantLock();public static Condition syncCondition = lock.newCondition();private Global() {}
}
  • Choreographer#doFrameGlobal.syncCondition.signal();通知另一条线程更新画面

com/xhbruce/ui/MySurfaceView.java

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {private static String TAG = "MySurfaceView";private SurfaceHolder mSurfaceHolder;private int autoNum = 0;private Paint mPaint = new Paint();public MySurfaceView(Context context) {this(context, null);}public MySurfaceView(Context context, AttributeSet attrs) {this(context, attrs , 0);}public MySurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mSurfaceHolder = this.getHolder();mSurfaceHolder.addCallback(this);Log.d(TAG, "MySurfaceView(3) holder=" + mSurfaceHolder.toString());}public MySurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);mSurfaceHolder = this.getHolder();mSurfaceHolder.addCallback(this);Log.d(TAG, "MySurfaceView(4) holder=" + mSurfaceHolder.toString());}@Overridepublic void surfaceCreated(@NonNull SurfaceHolder holder) {Log.d(TAG, "surfaceCreated() holder=" + holder.toString());new Thread(this).start();
//        draw();//画蓝色或绿色}@Overridepublic void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {}@Overridepublic void surfaceDestroyed(@NonNull SurfaceHolder holder) {}@Overridepublic void run() {while (true) {Log.d(TAG, "run() autoNum=" + autoNum);Global.lock.lock();try {Global.syncCondition.await();//在这里等待vsync到来的通知消息} catch (InterruptedException e) {e.printStackTrace();} finally {Global.lock.unlock();}draw();//画蓝色或绿色}}private void draw() {Canvas mCanvas = null;try {mCanvas = mSurfaceHolder.lockCanvas();if (autoNum % 2 == 0) {mPaint.setColor(Color.BLUE);//如果为双数则画面画成蓝色} else {mPaint.setColor(Color.GREEN);//如果为单数则画面画成绿色}mCanvas.drawRect(0, 0, getRight(), getBottom(), mPaint);} catch (Exception e) {e.printStackTrace();} finally {if (mCanvas != null) {mSurfaceHolder.unlockCanvasAndPost(mCanvas);}}Log.d(TAG, "draw() autoNum=" + autoNum);autoNum++;//数字加1}
}

对应Activity和xml布局文件:
com/xhbruce/surfaceviewtest/MySurfaceViewTest.java

public class MySurfaceViewTest extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_my_surface_view_test);Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() {@Overridepublic void doFrame(long frameTimeNanos) {//当vsync信号来时会调用到这里Global.lock.lock();try {Global.syncCondition.signal();//通知另一条线程更新画面} catch (Exception e) {e.printStackTrace();} finally {Global.lock.unlock();}Choreographer.getInstance().removeFrameCallback(this);Choreographer.getInstance().postFrameCallback(this);}});}
}

layout/activity_my_surface_view_test.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MySurfaceViewTest"><com.xhbruce.ui.MySurfaceViewandroid:layout_width="match_parent"android:layout_height="match_parent" />
</LinearLayout>

1.3 结果

SurfaceView Demo

2、SurfaceView获取画布并显示

  • SurfaceHolder.lockCanvas()获得Canvas对象并锁定画布
  • SurfaceHolder.unlockCanvasAndPost(Canvas canvas)结束锁定画图,并提交改变,将图形显示。

2.1 SurfaceHolder.lockCanvas()

Surface的lock方法最终调用到GraphicBufferProducerdequeueBuffer函数获取一个Slot,如果Slot没有分配GraphicBuffer会在这时给它分配GraphicBuffer, 然后会返回一个带有BUFFER_NEEDS_REALLOCATION标记的flag, 应用侧看到这个flag后会通过requestBuffer和importBuffer接口把GraphicBuffer映射到自已的进程空间。

在这里插入图片描述

2.2 SurfaceHolder.unlockCanvasAndPost(Canvas canvas)

SurfaceView在更新视图时用到了两张Canvas,一张frontCanvas和一张backCanvas,每次实际显示的是frontCanvas,backCanvas存储的是上一次更改前的视图,当使用lockCanvas()获取画布时,得到的实际上是backCanvas而不是正在显示的frontCanvas,之后你在获取到的backCanvas上绘制新视图,再unlockCanvasAndPost(Canvas canvas)此视图,那么上传的这张canvas将替换原来的frontCanvas作为新的frontCanvas,原来的frontCanvas将切换到后台作为backCanvas。

在这里插入图片描述

http://www.lryc.cn/news/126323.html

相关文章:

  • 【Spring系列篇--关于IOC的详解】
  • __ob__: Observer 后缀的数组的取值方式
  • 时序预测 | MATLAB实现WOA-CNN-BiLSTM鲸鱼算法优化卷积双向长短期记忆神经网络时间序列预测
  • Java基础知识点
  • 攻防世界-web-fileclude
  • 【100天精通python】Day36:GUI界面编程_高级功能操作和示例
  • 无涯教程-Perl - sub函数
  • wpf控件上移下移,调整子集控件显示顺序
  • cesium学习记录08-鼠标绘制多边形
  • rocketMq启动broker报错找不到或无法加载主类 Files\Java\jdk1.8.0_171\lib\dt.jar;C:\Program]
  • Linux touch 命令指南大全
  • 华为网络篇 RIPv2的基础配置-25
  • fastadmin 下拉多级分类
  • 时序预测 | MATLAB实现基于CNN-LSTM卷积长短期记忆神经网络的时间序列预测-递归预测未来(多指标评价)
  • RabbitMQ工作流程详解
  • LabVIEW使用图像处理进行交通控制性能分析
  • CentOS 7 下 Keepalived + Nginx 实现双机高可用
  • 【Linux】IO多路转接——select接口
  • error_Network Error
  • Python爱心光波
  • 【分布式】Viewstamped Replication Revisited
  • 微服务07-分布式缓存
  • QGraphicsView放大时,paint有时不被调用,导致图像绘制不出来(2)
  • 深入理解设计模式-创建型之建造者模式(与工厂区别)
  • Centos7多台服务器免密登录
  • C语言实现哈希搜索算法
  • MySQL卸载并重装指定版本
  • 文件IO编程 1 2
  • Java后端框架模块整合
  • 17 synchronized关键字使用 synchronized方法、synchronized块