SurfaceView 单线程与多线程画图的比较例子

本文通过实例展示了SurfaceView在单线程和多线程下进行绘图的差异,详细解析了相关代码实现,涉及Android布局、按钮处理以及线程管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

资源里有用到的四张图:


main.xml :


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <LinearLayout android:id="@+id/LinearLayout01"  
        android:layout_width="wrap_content" android:layout_height="wrap_content">  
        <Button android:id="@+id/Button01" android:layout_width="wrap_content"  
            android:layout_height="wrap_content" android:text="单个独立线程"></Button>  
        <Button android:id="@+id/Button02" android:layout_width="wrap_content"  
            android:layout_height="wrap_content" android:text="两个独立线程"></Button>
        <Button android:id="@+id/Button04" android:layout_width="wrap_content"  
            android:layout_height="wrap_content" android:text="停止"></Button>  
        <Button android:id="@+id/Button03" android:layout_width="wrap_content"  
            android:layout_height="wrap_content" android:text="退出"></Button>
    </LinearLayout>  
    <SurfaceView android:id="@+id/SurfaceView01"  
        android:layout_width="fill_parent" android:layout_height="fill_parent"></SurfaceView>  

</LinearLayout>


java代码:

package com.vince.base;

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 SurfaceViewWithThreadDemo extends Activity {
    /** Called when the activity is first created. */
	Button btnSingleThread, btnDoubleThread, btnExit, btnStop;  
    SurfaceView sfv;  
    SurfaceHolder sfh;  
    ArrayList<Integer> imgList = new ArrayList<Integer>();  
    int imgWidth, imgHeight;  
    Bitmap bitmap;
    
    Bitmap[] bitmapArray;//图片缓冲区
    boolean[] bitmapFlag;//图片是否缓冲好的标志
    int arraySize;//缓冲区大小
    Load_DrawImage load_DrawImage;//单线程读写的线程
    LoadImage loadImage;//多线程读图片的线程
    DrawImage drawImage;//多线程画图片的线程
    
    @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);  
        btnExit = (Button) this.findViewById(R.id.Button03);
        btnStop = (Button) this.findViewById(R.id.Button04);
        
        btnSingleThread.setOnClickListener(new ClickEvent());  
        btnDoubleThread.setOnClickListener(new ClickEvent());  
        btnExit.setOnClickListener(new ClickEvent());
        btnStop.setOnClickListener(new ClickEvent());
        
        sfv = (SurfaceView) this.findViewById(R.id.SurfaceView01);  
        sfh = sfv.getHolder();  
        sfh.addCallback(new MyCallBack());// 自动运行surfaceCreated以及surfaceChanged  
        
        load_DrawImage = null;
        loadImage = null;
        drawImage = null;
    }
    
    class ClickEvent implements View.OnClickListener {  
    	  
        @Override  
        public void onClick(View v) {  
  
            if (v == btnSingleThread) 
            {
            	if(load_DrawImage == null)
            		load_DrawImage = new Load_DrawImage(0, 0);
                if(!load_DrawImage.isAlive())
                	load_DrawImage.start();//单线程读取并绘图  
            } 
            else if (v == btnDoubleThread) 
            {  
            	if(loadImage == null)
            		loadImage = new LoadImage();
            	if(!loadImage.isAlive()) 
            		loadImage.start();//读取线程
            	if(drawImage == null)
            		drawImage = new DrawImage(imgWidth + 10, 0);
            	if(!drawImage.isAlive())
            		drawImage.start();//绘图线程
            }  
            else if (v == btnExit)
            {//退出时先关闭线程
            	if(load_DrawImage != null && load_DrawImage.isAlive())
            	{
            		load_DrawImage.interrupt();
            		try {
						load_DrawImage.join();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
            		load_DrawImage = null;
            	}
            	if(loadImage != null && loadImage.isAlive()) 
            	{
            		loadImage.interrupt();
            		try {
						loadImage.join();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
            		loadImage = null;
            	}
            	if(drawImage != null && drawImage.isAlive()) 
            	{
            		drawImage.interrupt();
            		try {
						drawImage.join();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
            		drawImage = null;
            	}
            	System.exit(0);
            }
            else if( v == btnStop)
            {//停止所有线程
            	if(load_DrawImage != null && load_DrawImage.isAlive())
            	{
            		load_DrawImage.interrupt();
            		try {
						load_DrawImage.join();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
            		load_DrawImage = null;
            	}
            	if(loadImage != null && loadImage.isAlive()) 
            	{
            		loadImage.interrupt();
            		try {
						loadImage.join();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
            		loadImage = null;
            	}
            	if(drawImage != null && drawImage.isAlive()) 
            	{
            		drawImage.interrupt();
            		try {
						drawImage.join();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
            		drawImage = null;
            	}
            }
        }  
  
    }  
    
    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 (!"ic_launcher".equals(field.getName()))// 除了ic_launcher之外的图片  
                {  
                    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(); 
            
            arraySize = 2;//缓冲区大小
            bitmapArray = new Bitmap[arraySize];
            bitmapFlag = new boolean[arraySize];
            for(int s = 0; s < arraySize; s++)
            {
            	bitmapFlag[s] = false;//初始化为图片没缓冲好
            }
        }  
  
        @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) {  
            	if(Thread.interrupted()) break;
                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;  
        int i;
  
        public DrawImage(int x, int y) {  
            this.x = x;  
            this.y = y;  
        }  
  
        public void run() {  
        	i = 0;
            while (true) {  
            	if(Thread.interrupted()) break;
            	/*
                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);// 更新屏幕显示内容
                }  
                */
            	if(bitmapFlag[i])
            	{
            		if (bitmapArray[i] != null) {//如果图像有效  
                        Canvas c = sfh.lockCanvas(new Rect(this.x, this.y, this.x  
                                + imgWidth, this.y + imgHeight));  
                        c.drawBitmap(bitmapArray[i], this.x, this.y, new Paint());  
                        sfh.unlockCanvasAndPost(c);// 更新屏幕显示内容
                    }
            		bitmapFlag[i] = false;
            	}
            	i++;
            	if(i == arraySize)
            	{
            		i = 0;
            	}
            }  
        }  
    };  
    
    /* 
     * 只负责读取图片的线程 
     */  
    class LoadImage extends Thread {
        int imgIndex = 0;  
        int i;
  
        public void run() { 
        	i = 0;
            while (true) {  
        	if(Thread.interrupted()) break;
            	/*
                bitmap = BitmapFactory.decodeResource(getResources(),  
                        imgList.get(imgIndex));  
                imgIndex++;  
                if (imgIndex == imgList.size())//如果到尽头则重新读取  
                    imgIndex = 0;  
                */
            	if(!bitmapFlag[i])
            	{
            		bitmapArray[i] = BitmapFactory.decodeResource(getResources(),  
                            			imgList.get(imgIndex));  
                    imgIndex++;  
                    if (imgIndex == imgList.size())//如果到尽头则重新读取  
                    {
                    	imgIndex = 0;
                    }
            		bitmapFlag[i] = true;
            	}
            	i++;
            	if(i == arraySize)
            	{
            		i = 0;
            	}
            }  
        }  
    };  
}

没了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值