逝姿飞鱼

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

  之前做下载程序的时候没有注意过效率,在这个靠硬件来拉开用户体验的时代应用程序内算法效率很容易被忽视。

  以前的思路是用 inputstream 来down数据,存到 byte[] 中直接写到文件中。

  后来重温编程之美的时候看到了类似的文章。如果要提高下载效率,需要把写文件和读文件分开,一个线程负责读数据,另一个线程负责写数据,数据池一定要用线程安全的数据结构。

 

     ***********************************************我是下载和Surfaceview的分割线***************************************************

  

   在用SurfaceView做动画的时候也是同样的道理,如果读出一张Bitmap再去显示,界面肯定会卡。

  需要使用双缓冲,开辟两个线程,一个用来读图,一个用来显示。

  下面是示例代码:

  

  1 package com.testSurfaceView;
  2 
  3 import java.lang.reflect.Field;
  4 import java.util.ArrayList;
  5 import android.app.Activity;
  6 import android.graphics.Bitmap;
  7 import android.graphics.BitmapFactory;
  8 import android.graphics.Canvas;
  9 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 }
posted on 2012-06-17 21:34  逝姿飞鱼  阅读(204)  评论(0编辑  收藏  举报