Android提高第三篇之SurfaceView与多线程的混搭
来源:互联网 发布:ios 面向切面编程 编辑:程序博客网 时间:2024/04/24 15:29
上一篇简单介绍了SurfaceView的基本使用,这次就介绍SurfaceView与多线程的混搭。SurfaceView与多线程混搭,是为了防止动画闪烁而实现的一种多线程应用。android的多线程用法与JAVA的多线程用法完全一样,本文不做多线程方面的介绍了。直接讲解SurfaceView与多线程的混合使用,即开一条线程专门读取图片,另外一条线程专门绘图。
本文程序运行截图如下,左边是开单个线程读取并绘图,右边是开两个线程,一个专门读取图片,一个专门绘图:
对比一下,右边动画的帧速明显比左边的快,左右两者都没使用Thread.sleep()。为什么要开两个线程一个读一个画,而不去开两个线程像左边那样都“边读边画”呢?因为SurfaceView每次绘图都会锁定Canvas,也就是说同一片区域这次没画完下次就不能画,因此要提高动画播放的效率,就得开一条线程专门画图,开另外一条线程做预处理的工作。
main.xml的源码:
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>
本文程序的源码:
01.package com.testSurfaceView; 02. 03.import java.lang.reflect.Field; 04.import java.util.ArrayList; 05.import android.app.Activity; 06.import android.graphics.Bitmap; 07.import android.graphics.BitmapFactory; 08.import android.graphics.Canvas; 09.import android.graphics.Paint; 10.import android.graphics.Rect; 11.import android.os.Bundle; 12.import android.util.Log; 13.import android.view.SurfaceHolder; 14.import android.view.SurfaceView; 15.import android.view.View; 16.import android.widget.Button; 17. 18.public class testSurfaceView extends Activity { 19. /** Called when the activity is first created. */ 20. Button btnSingleThread, btnDoubleThread; 21. SurfaceView sfv; 22. SurfaceHolder sfh; 23. ArrayList<Integer> imgList = new ArrayList<Integer>(); 24. int imgWidth, imgHeight; 25. Bitmap bitmap;//独立线程读取,独立线程绘图 26. 27. @Override 28. public void onCreate(Bundle savedInstanceState) { 29. super.onCreate(savedInstanceState); 30. setContentView(R.layout.main); 31. 32. btnSingleThread = (Button) this.findViewById(R.id.Button01); 33. btnDoubleThread = (Button) this.findViewById(R.id.Button02); 34. btnSingleThread.setOnClickListener(new ClickEvent()); 35. btnDoubleThread.setOnClickListener(new ClickEvent()); 36. sfv = (SurfaceView) this.findViewById(R.id.SurfaceView01); 37. sfh = sfv.getHolder(); 38. sfh.addCallback(new MyCallBack());// 自动运行surfaceCreated以及surfaceChanged 39. } 40. 41. class ClickEvent implements View.OnClickListener { 42. 43. @Override 44. public void onClick(View v) { 45. 46. if (v == btnSingleThread) { 47. new Load_DrawImage(0, 0).start();//开一条线程读取并绘图 48. } else if (v == btnDoubleThread) { 49. new LoadImage().start();//开一条线程读取 50. new DrawImage(imgWidth + 10, 0).start();//开一条线程绘图 51. } 52. 53. } 54. 55. } 56. 57. class MyCallBack implements SurfaceHolder.Callback { 58. 59. @Override 60. public void surfaceChanged(SurfaceHolder holder, int format, int width, 61. int height) { 62. Log.i("Surface:", "Change"); 63. 64. } 65. 66. @Override 67. public void surfaceCreated(SurfaceHolder holder) { 68. Log.i("Surface:", "Create"); 69. 70. // 用反射机制来获取资源中的图片ID和尺寸 71. Field[] fields = R.drawable.class.getDeclaredFields(); 72. for (Field field : fields) { 73. if (!"icon".equals(field.getName()))// 除了icon之外的图片 74. { 75. int index = 0; 76. try { 77. index = field.getInt(R.drawable.class); 78. } catch (IllegalArgumentException e) { 79. // TODO Auto-generated catch block 80. e.printStackTrace(); 81. } catch (IllegalAccessException e) { 82. // TODO Auto-generated catch block 83. e.printStackTrace(); 84. } 85. // 保存图片ID 86. imgList.add(index); 87. } 88. } 89. // 取得图像大小 90. Bitmap bmImg = BitmapFactory.decodeResource(getResources(), 91. imgList.get(0)); 92. imgWidth = bmImg.getWidth(); 93. imgHeight = bmImg.getHeight(); 94. } 95. 96. @Override 97. public void surfaceDestroyed(SurfaceHolder holder) { 98. Log.i("Surface:", "Destroy"); 99. 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.}
本文来自:http://blog.csdn.net/hellogv/article/details/5986835
- Android提高第三篇之SurfaceView与多线程的混搭
- Android提高第三篇之SurfaceView与多线程的混搭
- Android提高第三篇之SurfaceView与多线程的混搭
- Android提高第三篇之SurfaceView与多线程的混搭
- Android提高第三篇之SurfaceView与多线程的混搭
- Android提高第三篇之SurfaceView与多线程的混搭
- Android提高第三篇之SurfaceView与多线程的混搭
- Android提高第三篇之SurfaceView与多线程的混搭
- Android提高第三篇之SurfaceView(下)
- Android提高第三篇之SurfaceView(下)
- 3.SurfaceView与多线程的混搭
- SurfaceView与多线程的混搭
- SurfaceView与多线程的混搭
- Android提高第二篇之SurfaceView的基本使用
- Android提高第二篇之SurfaceView的基本使用
- Android提高第二篇之SurfaceView的基本使用
- Android提高第二篇之SurfaceView的基本使用
- Android提高第二篇之SurfaceView的基本使用
- c++基础——名字的作用域
- 教你简单区分模拟电源、开关电源、数字电源
- 看原理图之GPIO
- Specifying Object Implementations 指定对象的实现
- Wikioi 天梯 机票打折(2235)
- Android提高第三篇之SurfaceView与多线程的混搭
- 小程序(十)字符串替换2
- 关键路径
- poj 1936 All in All (字符串处理)
- 华为上机题
- STL 中的vector用法
- HDOJ4196 remoteland
- 使用mina传输大字节数组
- HDU 4050 wolf5x