双缓冲是为了防止动画闪烁而实现的一种多线程应用,基于SurfaceView的双缓冲实现很简单,开一条线程并在其中绘图即可。本文介绍基于SurfaceView的双缓冲实现,以及介绍类似的更高效的实现方法。
本文程序运行截图如下,左边是开单个线程读取并绘图,右边是开两个线程,一个专门读取图片,一个专门绘图:
对比一下,右边动画的帧速明显比左边的快,左右两者都没使用Thread.sleep()。为什么要开两个线程一个读一个画,而不去开两个线程像左边那样都 “边读边画”呢?因为SurfaceView每次绘图都会锁定Canvas,也就是说同一片区域这次没画完下次就不能画,因此要提高双缓冲的效率,就得开一条线程专门画图,开另外一条线程做预处理的工作。
main.xml
view sourceprint?
01 <?xml version="1.0" encoding="utf-8"?>
02 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
03 android:layout_width="fill_parent" android:layout_height="fill_parent"
04 android:orientation="vertical">
05
06 <LinearLayout android:id="@+id/LinearLayout01"
07 android:layout_width="wrap_content" android:layout_height="wrap_content">
08 <Button android:id="@+id/Button01" android:layout_width="wrap_content"
09 android:layout_height="wrap_content" android:text="单个独立线程"></Button>
10 <Button android:id="@+id/Button02" android:layout_width="wrap_content"
11 android:layout_height="wrap_content" android:text="两个独立线程"></Button>
12 </LinearLayout>
13 <SurfaceView android:id="@+id/SurfaceView01"
14 android:layout_width="fill_parent" android:layout_height="fill_parent"></SurfaceView>
15 </LinearLayout>
[代码] TestSurfaceView.java
view sourceprint?
001 package com.testSurfaceView;
002
003 import java.lang.reflect.Field;
004 import java.util.ArrayList;
005 import android.app.Activity;
006 import android.graphics.Bitmap;
007 import android.graphics.BitmapFactory;
008 import android.graphics.Canvas;
009 import android.graphics.Paint;
010 import android.graphics.Rect;
011 import android.os.Bundle;
012 import android.util.Log;
013 import android.view.SurfaceHolder;
014 import android.view.SurfaceView;
015 import android.view.View;
016 import android.widget.Button;
017
018 public class TestSurfaceView extends Activity {
019 /** Called when the activity is first created. */
020 Button btnSingleThread, btnDoubleThread;
021 SurfaceView sfv;
022 SurfaceHolder sfh;
023 ArrayList<Integer> imgList = new ArrayList<Integer>();
024 int imgWidth, imgHeight;
025 Bitmap bitmap;//独立线程读取,独立线程绘图
026
027 @Override
028 public void onCreate(Bundle savedInstanceState) {
029 super.onCreate(savedInstanceState);
030 setContentView(R.layout.main);
031
032 btnSingleThread = (Button) this.findViewById(R.id.Button01);
033 btnDoubleThread = (Button) this.findViewById(R.id.Button02);
034 btnSingleThread.setOnClickListener(new ClickEvent());
035 btnDoubleThread.setOnClickListener(new ClickEvent());
036 sfv = (SurfaceView) this.findViewById(R.id.SurfaceView01);
037 sfh = sfv.getHolder();
038 sfh.addCallback(new MyCallBack());// 自动运行surfaceCreated以及surfaceChanged
039 }
040
041 class ClickEvent implements View.OnClickListener {
042
043 @Override
044 public void onClick(View v) {
045
046 if (v == btnSingleThread) {
047 new Load_DrawImage(0, 0).start();//开一条线程读取并绘图
048 } else if (v == btnDoubleThread) {
049 new LoadImage().start();//开一条线程读取
050 new DrawImage(imgWidth + 10, 0).start();//开一条线程绘图
051 }
052
053 }
054
055 }
056
057 class MyCallBack implements SurfaceHolder.Callback {
058
059 @Override
060 public void surfaceChanged(SurfaceHolder holder, int format, int width,
061 int height) {
062 Log.i("Surface:", "Change");
063
064 }
065
066 @Override
067 public void surfaceCreated(SurfaceHolder holder) {
068 Log.i("Surface:", "Create");
069
070 // 用反射机制来获取资源中的图片ID和尺寸
071 Field[] fields = R.drawable.class.getDeclaredFields();
072 for (Field field : fields) {
073 if (!"icon".equals(field.getName()))// 除了icon之外的图片
074 {
075 int index = 0;
076 try {
077 index = field.getInt(R.drawable.class);
078 } catch (IllegalArgumentException e) {
079 // TODO Auto-generated catch block
080 e.printStackTrace();
081 } catch (IllegalAccessException e) {
082 // TODO Auto-generated catch block
083 e.printStackTrace();
084 }
085 // 保存图片ID
086 imgList.add(index);
087 }
088 }
089 // 取得图像大小
090 Bitmap bmImg = BitmapFactory.decodeResource(getResources(),
091 imgList.get(0));
092 imgWidth = bmImg.getWidth();
093 imgHeight = bmImg.getHeight();
094 }
095
096 @Override
097 public void surfaceDestroyed(SurfaceHolder holder) {
098 Log.i("Surface:", "Destroy");
099
100 }
101
102 }
103
104 /**
105 * 读取并显示图片的线程
106 */
107 class Load_DrawImage extends Thread {
108 int x, y;
109 int imgIndex = 0;
110
111 public Load_DrawImage(int x, int y) {
112 this.x = x;
113 this.y = y;
114 }
115
116 public void run() {
117 while (true) {
118 Canvas c = sfh.lockCanvas(new Rect(this.x, this.y, this.x
119 + imgWidth, this.y + imgHeight));
120 Bitmap bmImg = BitmapFactory.decodeResource(getResources(),
121 imgList.get(imgIndex));
122 c.drawBitmap(bmImg, this.x, this.y, new Paint());
123 imgIndex++;
124 if (imgIndex == imgList.size())
125 imgIndex = 0;
126
127 sfh.unlockCanvasAndPost(c);// 更新屏幕显示内容
128 }
129 }
130 };
131
132 /**
133 * 只负责绘图的线程
134 */
135 class DrawImage extends Thread {
136 int x, y;
137
138 public DrawImage(int x, int y) {
139 this.x = x;
140 this.y = y;
141 }
142
143 public void run() {
144 while (true) {
145 if (bitmap != null) {//如果图像有效
146 Canvas c = sfh.lockCanvas(new Rect(this.x, this.y, this.x
147 + imgWidth, this.y + imgHeight));
148
149 c.drawBitmap(bitmap, this.x, this.y, new Paint());
150
151 sfh.unlockCanvasAndPost(c);// 更新屏幕显示内容
152 }
153 }
154 }
155 };
156
157 /**
158 * 只负责读取图片的线程
159 */
160 class LoadImage extends Thread {
161 int imgIndex = 0;
162
163 public void run() {
164 while (true) {
165 bitmap = BitmapFactory.decodeResource(getResources(),
166 imgList.get(imgIndex));
167 imgIndex++;
168 if (imgIndex == imgList.size())//如果到尽头则重新读取
169 imgIndex = 0;
170 }
171 }
172 };
173 }
- 大小: 655 KB
分享到:
相关推荐
源码参考,欢迎下载
Android一词的本义指“机器人”,同时也是Google于2007年11月5日宣布的基于Linux平台的开源手机操作系统的名称,该平台由操作系统、中间件、用户界面和应用软件组成,号称是为移动终端打造的真正开放和完整的移动...
这次介绍SurfaceView的双缓冲使用。双缓冲是为了防止动画闪烁而实现的一种多线程应用,基于SurfaceView的双缓冲实现很简单,开一条线程并在其中绘图即可。
Android应用源码开发Demo,主要用于毕业设计学习。
Android应用源码之VIEW双缓冲与SurfaceView比较.zip项目安卓应用源码下载Android应用源码之VIEW双缓冲与SurfaceView比较.zip项目安卓应用源码下载 1.适合学生毕业设计研究参考 2.适合个人学习研究参考 3.适合公司...
Android应用源码之VIEW双缓冲与SurfaceView比较.zip
android应用源码,安卓应用源码下载,android游戏源码下载,android游戏源代码,安卓游戏代码,android软件源代码,安卓程序源代码下载,安卓软件源码,android源码下载,安卓源码下载,安卓源代码,android软件源代码下载。
android 源码学习. 资料部分来源于合法的互联网渠道收集和整理,供大家学习参考与交流。本人不对所涉及的版权问题或内容负法律责任。如有侵权,请通知本人删除。感谢CSDN官方提供大家交流的平台
Android一词的本义指“机器人”,同时也是Google于2007年11月5日宣布的基于Linux平台的开源手机操作系统的名称,该平台由操作系统、中间件、用户界面和应用软件组成,号称是首个为移动终端打造的真正开放和完整的...
Android应用源码安卓源码(172个...VIEW双缓冲与SurfaceView比较.zip weibo4andriod-2011-01-14.zip WordPress for Android zirco-browser浏览器源码.rar Zirco-browser:超越海豚的开源浏览器.rar zz-doctor中医大夫助
5.2.10 双缓冲技术 5.2.11 全屏显示 5.2.12 获得屏幕属性 5.3 动画实现 5.3.1 Tween动画 5.3.2 Frame动画 5.3.3 GIF动画播放 5.4 小结 第6章 Android数据存储 6.1 Android数据存储初探 6.2 ...
5.2.10 双缓冲技术 5.2.11 全屏显示 5.2.12 获得屏幕属性 5.3 动画实现 5.3.1 Tween动画 5.3.2 Frame动画 5.3.3 GIF动画播放 5.4 小结 第6章 Android数据存储 6.1 Android数据存储初探 6.2 ...
5.2.10 双缓冲技术 5.2.11 全屏显示 5.2.12 获得屏幕属性 5.3 动画实现 5.3.1 Tween动画 5.3.2 Frame动画 5.3.3 GIF动画播放 5.4 小结 第6章 Android数据存储 6.1 Android数据存储初探 6.2 数据存储之Shared ...
5.2.10 双缓冲技术 5.2.11 全屏显示 5.2.12 获得屏幕属性 5.3 动画实现 5.3.1 Tween动画 5.3.2 Frame动画 5.3.3 GIF动画播放 5.4 小结 第6章 Android数据存储 6.1 Android数据存储初探 6.2 数据存储之Shared ...
ImageView 图片循环跑马灯的效果.rar ...VIEW双缓冲与SurfaceView比较.zip weibo4andriod-2011-01-14.zip WIFI 扫描 Demo.zip Zirco-browser:超越海豚的开源浏览器.rar zz-doctor中医大夫助理信息系统(简化版).zip
使用surfaceview,双缓冲技术,可应用于对播放实时性要求较高的视频
Swing的方便多了,默认就实现双缓冲功能,画面效果还挺流畅的。 感兴趣的可以下载玩玩:(游戏所用资源皆是网上找的,只供演示使用) 下载密码:111111 游戏源码下载: 点击链接加入QQ群聊: 或关注微信公众号:口袋...