栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 移动开发 > Android

21天学习android开发教程之SurfaceView与多线程的混搭

Android 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

21天学习android开发教程之SurfaceView与多线程的混搭

上一篇简单介绍了SurfaceView的基本使用,这次就介绍SurfaceView与多线程的混搭。SurfaceView与多线程混搭,是为了防止动画闪烁而实现的一种多线程应用。android的多线程用法与JAVA的多线程用法完全一样,本文不做多线程方面的介绍了。直接讲解SurfaceView与多线程的混合使用,即开一条线程专门读取图片,另外一条线程专门绘图。
        本文程序运行截图如下,左边是开单个线程读取并绘图,右边是开两个线程,一个专门读取图片,一个专门绘图:

 

对比一下,右边动画的帧速明显比左边的快,左右两者都没使用Thread.sleep()。为什么要开两个线程一个读一个画,而不去开两个线程像左边那样都“边读边画”呢?因为SurfaceView每次绘图都会锁定Canvas,也就是说同一片区域这次没画完下次就不能画,因此要提高动画播放的效率,就得开一条线程专门画图,开另外一条线程做预处理的工作。
main.xml的源码:



    
 

本文程序的源码:

package com.testSurfaceView;

import java.lang.reflect.Field;
import java.util.ArrayList;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;

public class testSurfaceView extends Activity {
    
    Button btnSingleThread, btnDoubleThread;
    SurfaceView sfv;
    SurfaceHolder sfh;
    ArrayList imgList = new ArrayList();
    int imgWidth, imgHeight;
    Bitmap bitmap;//独立线程读取,独立线程绘图

    @Override
    public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.main);

 btnSingleThread = (Button) this.findViewById(R.id.Button01);
 btnDoubleThread = (Button) this.findViewById(R.id.Button02);
 btnSingleThread.setonClickListener(new ClickEvent());
 btnDoubleThread.setonClickListener(new ClickEvent());
 sfv = (SurfaceView) this.findViewById(R.id.SurfaceView01);
 sfh = sfv.getHolder();
 sfh.addCallback(new MyCallBack());// 自动运行surfaceCreated以及surfaceChanged
    }

    class ClickEvent implements View.onClickListener {

 @Override
 public void onClick(View v) {

     if (v == btnSingleThread) {
  new Load_DrawImage(0, 0).start();//开一条线程读取并绘图
     } else if (v == btnDoubleThread) {
  new LoadImage().start();//开一条线程读取
  new DrawImage(imgWidth + 10, 0).start();//开一条线程绘图
     }

 }

    }

    class MyCallBack implements SurfaceHolder.Callback {

 @Override
 public void surfaceChanged(SurfaceHolder holder, int format, int width,
  int height) {
     Log.i("Surface:", "Change");

 }

 @Override
 public void surfaceCreated(SurfaceHolder holder) {
     Log.i("Surface:", "Create");

     // 用反射机制来获取资源中的图片ID和尺寸
     Field[] fields = R.drawable.class.getDeclaredFields();
     for (Field field : fields) {
  if (!"icon".equals(field.getName()))// 除了icon之外的图片
  {
      int index = 0;
      try {
   index = field.getInt(R.drawable.class);
      } catch (IllegalArgumentException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
      } catch (IllegalAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
      }
      // 保存图片ID
      imgList.add(index);
  }
     }
     // 取得图像大小
     Bitmap bmImg = BitmapFactory.decodeResource(getResources(),
      imgList.get(0));
     imgWidth = bmImg.getWidth();
     imgHeight = bmImg.getHeight();
 }

 @Override
 public void surfaceDestroyed(SurfaceHolder holder) {
     Log.i("Surface:", "Destroy");

 }

    }

    
    class Load_DrawImage extends Thread {
 int x, y;
 int imgIndex = 0;

 public Load_DrawImage(int x, int y) {
     this.x = x;
     this.y = y;
 }

 public void run() {
     while (true) {
  Canvas c = sfh.lockCanvas(new Rect(this.x, this.y, this.x
   + imgWidth, this.y + imgHeight));
  Bitmap bmImg = BitmapFactory.decodeResource(getResources(),
   imgList.get(imgIndex));
  c.drawBitmap(bmImg, this.x, this.y, new Paint());
  imgIndex++;
  if (imgIndex == imgList.size())
      imgIndex = 0;

  sfh.unlockCanvasAndPost(c);// 更新屏幕显示内容
     }
 }
    };

    
    class DrawImage extends Thread {
 int x, y;

 public DrawImage(int x, int y) {
     this.x = x;
     this.y = y;
 }

 public void run() {
     while (true) {
  if (bitmap != null) {//如果图像有效
      Canvas c = sfh.lockCanvas(new Rect(this.x, this.y, this.x
+ imgWidth, this.y + imgHeight));

      c.drawBitmap(bitmap, this.x, this.y, new Paint());

      sfh.unlockCanvasAndPost(c);// 更新屏幕显示内容
  }
     }
 }
    };

    
    class LoadImage extends Thread {
 int imgIndex = 0;

 public void run() {
     while (true) {
  bitmap = BitmapFactory.decodeResource(getResources(),
   imgList.get(imgIndex));
  imgIndex++;
  if (imgIndex == imgList.size())//如果到尽头则重新读取
      imgIndex = 0;
     }
 }
    };
}

以上就是本文的全部内容,希望对大家学习Android软件编程有所帮助。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/163312.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号