对android中的surfaceview的困惑,双缓冲区该怎么理解?

逆风小企鹅 2014-07-14 09:29:26
加精

这几天想在surfaceview中做个小东西,然后自己试着写了下demo,但是关于他的双缓冲,我一直无法理解,看了很多博客,也不是很明白。
demo很简单,就是获取surfaceview的画布,然后写上0~20的数字,也就是这个显示结果,让我看不明白,先贴效果图:


这是最后的显示画面。问题就是,为什么是间隔了两个数字?也就是说,第一帧:只显示0,第二帧:只显示1,第三帧:只显示2.。按我的理解,不应该是第三帧的时候显示:0 2 么?这样才像是两个画布,而不是三个。

可能问题有点幼稚,还望大神不吝赐教,或者有什么好博客可以推荐下,谢谢。

附源码:
public class MainActivity extends Activity implements Runnable {
Button button;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
Thread thread;
private final String TAG = "MainActivity.java";
private boolean isStarted = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init() {
button = (Button) findViewById(R.id.button1);
surfaceView = (SurfaceView) findViewById(R.id.surfaceView1);
surfaceHolder = surfaceView.getHolder();
thread = new Thread(this);
button.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (!isStarted) {
isStarted = true;
thread.start();
}
}
});
}

@Override
public void run() {
// TODO Auto-generated method stub
if (surfaceHolder == null) {
Log.i(TAG, "surfaceHolder==null");
return;
}
int i = 0;
Paint mPaint = new Paint();
mPaint.setColor(Color.WHITE);// 画笔为绿色
mPaint.setStrokeWidth(2);// 设置画笔粗细
mPaint.setTextSize(50);;
while (i < 20) {
Canvas canvas = surfaceHolder.lockCanvas();
canvas.drawText(""+i, 100, 50+50*i, mPaint);

surfaceHolder.unlockCanvasAndPost(canvas);// 解锁画布,提交画好的图像
i++;

try {
thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

}


布局文件:
<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="${packageName}.${activityClass}" >

<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="22dp"
android:text="开始" />

<SurfaceView
android:layout_below="@id/button1"
android:id="@+id/surfaceView1"
android:layout_width="match_parent"
android:layout_height="match_parent" />

</RelativeLayout>
...全文
5067 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
a953210725 2021-07-30
  • 打赏
  • 举报
回复

研究了下你这个现象,我的理解是这样的:
目前的Android版本是3缓冲,也就是有3个buffer用于绘制.
一对lockCanvas和unlockCanvasAndPost操作一般是一次完整的绘制操作,该操作后就会切换buffer(缓冲)
所以你循环20次该操作,本身的意义也就是在于最后最后一次绘制结果,
所以正常情况下,你期望应该是最后一次绘制结果 "19"

所以前面的数字只是之前绘制在该buffer上的数字,所以是随机的,但最终一定是19
而如果想要去除前面的绘制,应该在绘制前主动清理,如:
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);

huanxido 2015-08-23
  • 打赏
  • 举报
回复 8
很多人对SurfaceView的双缓冲理解并不对。 一般游戏里说的双缓冲防止画面闪烁,只是每一帧先绘制到bitmap再绘制到SurfaceView的canvas。 而框架中的Surface的双缓冲是另一个概念。 事实上不管是View还是SurfaceView都会使用到Surface双缓冲技术,在4.1以后更是引入了三缓冲。 楼主看到的画面实际上就是Surface的三缓冲造成的。使用SurfaceView每次lockCanvas获取到的画布都是1,2,3个画布轮流切换。 Surface的多缓冲是系统可以指定的, 4.1以前默认是2个,4.2以后默认是3个,厂商可以修改,最多可以使用32个缓冲区。
村口老张头 2015-08-15
  • 打赏
  • 举报
回复
我的也是隔4个,我还见过隔2个的,咋理解啊?
编程爱好者111 2015-07-19
  • 打赏
  • 举报
回复
我的隔4个数字,难道跟cpu个数有关?
jiayangcg 2015-03-01
  • 打赏
  • 举报
回复
楼主问题搞定了吗?我也有同样的问题搞不懂。
jeky_zhang2013 2014-07-21
  • 打赏
  • 举报
回复
这个估计要研究下底层硬件的处理方式
逆风小企鹅 2014-07-18
  • 打赏
  • 举报
回复
引用 13 楼 foruok 的回复:
有一个办法,就是你使用一个内存图片,每次把要绘制的东西先在它上面绘制好,保留你叠加的效果,lockCanvas 成功后把这个图片绘制到 SurfaceView 。 -------------------------- 博文决赛,投我一票,谢谢。
这个方法我也知道,但是我想知道的是为什么会出现这种现象...
foruok 2014-07-18
  • 打赏
  • 举报
回复
有一个办法,就是你使用一个内存图片,每次把要绘制的东西先在它上面绘制好,保留你叠加的效果,lockCanvas 成功后把这个图片绘制到 SurfaceView 。 -------------------------- 博文决赛,投我一票,谢谢。
周堆栈 2014-07-16
  • 打赏
  • 举报
回复
没见过,帮顶下~
逆风小企鹅 2014-07-16
  • 打赏
  • 举报
回复
引用 5 楼 cclovescw 的回复:
楼上的资料不错,此帖推荐了
版主能解答下我的困惑么?就是9楼的回帖
韩曙亮 2014-07-15
  • 打赏
  • 举报
回复
参考博客 : -- 双缓冲demo : http://blog.csdn.net/imyfriend/article/details/8033823 应该是你的demo那个博客 -- 双缓冲理解 : http://www.apkbus.com/android-99309-1-1.html 分析SurfaceView源码 -- 双缓冲与单缓冲区别 : http://blog.csdn.net/lcfeng1982/article/details/7431446 -- 双缓冲与但缓冲动画绘制区别demo : http://blog.csdn.net/geolo/article/details/6024761
韩曙亮 2014-07-15
  • 打赏
  • 举报
回复
SurfaceView 有两块 canvas 画布, 画布一 在显示的时候, 画布二 已经开始绘制另一个图像, 两块画布交替显示, 因此 在SurfaceView 上打印数字的时候, 可能会出现打印出来的数字不一致, 两块画布的内容不一样的原因; 如果绘制动画 或者 动态图片, 双缓冲会使界面更加流畅, 但是绘制连续的数据的时候会出现交替现象, 这是因为两个缓冲区是不同步的
逆风小企鹅 2014-07-15
  • 打赏
  • 举报
回复
引用 1 楼 jeky198306 的回复:
没见过,帮顶下~~
饿,我还以为有人知道答案了...不过还是谢谢
逆风小企鹅 2014-07-15
  • 打赏
  • 举报
回复
引用 7 楼 RrMoon 的回复:
双缓冲主要是为了解决 反复局部刷屏带来的闪烁。把要画的东西先画到一个内存区域里,然后整体的一次性画出来,游戏通常会采用此方式。
那能解释下#9楼的情况么?谢谢
逆风小企鹅 2014-07-15
  • 打赏
  • 举报
回复
引用 3 楼 han1202012 的回复:
SurfaceView 有两块 canvas 画布, 画布一 在显示的时候, 画布二 已经开始绘制另一个图像, 两块画布交替显示, 因此 在SurfaceView 上打印数字的时候, 可能会出现打印出来的数字不一致, 两块画布的内容不一样的原因;

如果绘制动画 或者 动态图片, 双缓冲会使界面更加流畅, 但是绘制连续的数据的时候会出现交替现象, 这是因为两个缓冲区是不同步的


谢谢回答,按您的意思,也就是说运行程序后在我们的屏幕上,将会出现两个界面,也就是画布一和画布二分别呈现的,也就是您推荐给我的第一个博客:http://blog.csdn.net/imyfriend/article/details/8033823 中所说的,出现单双数出现在不同的界面的情况。
但是,不知道您是否运行过程序,实际的效果并不是他说的那样子,实际呈现的将会是三个界面:界面一:“0,3,6,9,...”,界面二:”1,4,7,10,... “,界面三:“2,5,8,11,...”,并不是预期的那样,所以能否讲的详细点?
界面一:
界面二:
界面三:
qq_17699095 2014-07-15
  • 打赏
  • 举报
回复
R小菜鸟R 2014-07-15
  • 打赏
  • 举报
回复
双缓冲主要是为了解决 反复局部刷屏带来的闪烁。把要画的东西先画到一个内存区域里,然后整体的一次性画出来,游戏通常会采用此方式。
BestDraven 2014-07-15
  • 打赏
  • 举报
回复
SurfaceView 有两块 canvas 画布, 画布一 在显示的时候, 画布二 已经开始绘制另一个图像, 两块画布交替显示, 因此 在SurfaceView 上打印数字的时候, 可能会出现打印出来的数字不一致, 两块画布的内容不一样的原因; 如果绘制动画 或者 动态图片, 双缓冲会使界面更加流畅, 但是绘制连续的数据的时候会出现交替现象, 这是因为两个缓冲区是不同步的
  • 打赏
  • 举报
回复
楼上的资料不错,此帖推荐了
jeky_zhang2013 2014-07-14
  • 打赏
  • 举报
回复
没见过,帮顶下~~
Android Camera开发入门:目录 第一篇: 前景  一、Android Camera开发前景;      1)camera相关应用的领域      2)相关岗位介绍;      3)市场招聘介绍;      4)发展前景介绍;  二、学习这门课的重要性;      1)适合的人群;      2)熟悉和了解Android Camera 应用开发流程的重要性 第二篇: 开发环境安装  一、jdk、sdk的配置;  二、android studio的安装介绍;  三、adb命令的使用; 第三篇: Camera 常用api和最新框架介绍  一、android camera api介绍      1)camera1、camera2 区别;      2)camera 1、camera2 常用api介绍;      3)android camerax;  二、android camera最新框架介绍 第四篇:Camera api1实现预览、拍照、录像功能  一、预览  二、拍照  三、录像  四、获取实时预览流 第五篇: Camera2相机 打开功能实现第六篇: Camera2相机 预览功能实现  1)surfaceview、textureview 第七篇: Camera2相机 拍照功能实现 1)单拍; 第八篇:Camera2相机 录像功能实现1)正常录像 第九篇:Camera2预览方向、拍照方向设置     1) 预览变形问题如何处理? 第十篇:YUV流处理  1)如何获取实时预览流?  2)  思考:双码流方案如何实现?一边本地录像,一边后台推流 第十一篇:dumpsys media.camera 第十二篇:Camera2 Zoom变焦第十三篇:人脸识别(android 原生 & 三方人脸识别算法)第十四篇:Uvc UsbCamera第十五篇:Android Camera2拍摄RAW图第十六篇: Android Camera2同时打开前后摄 并 录像第十七篇: Android Camera2 视频慢动作  附:1)提供android开发相关资源      软件工具、Android相关学习书籍、学习相关网站博客等链接2)提供课程讲解设计到的App 源码    * Camera API1使用源码    * Camera API2使用源码    * 调用三方算法人脸识别源码    *  录像慢动作源码    * Uvc UsbCamera相关源码3)课件

80,337

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧