21 일 동안 안 드 로 이 드 개발 튜 토리 얼 의 Surface View 와 다 중 스 레 드 의 혼합 학습

4전편Surface View 의 기본 적 인 사용 을 간단하게 소 개 했 고 이번 에는 Surface View 와 다 중 스 레 드 의 혼합 을 소개 합 니 다.Surface View 와 다 중 스 레 드 가 혼 합 된 것 은 애니메이션 의 반 짝 임 을 방지 하기 위 한 다 중 스 레 드 응용 입 니 다.안 드 로 이 드 의 다 중 스 레 드 용법 은 JAVA 의 다 중 스 레 드 용법 과 똑 같 습 니 다.본 고 는 다 중 스 레 드 방면 의 소 개 를 하지 않 습 니 다.SurfaceView 와 다 중 스 레 드 의 혼합 사용 을 직접 설명 합 니 다.즉,하나의 스 레 드 를 열 어 그림 을 읽 고 다른 스 레 드 는 그림 을 전문 적 으로 그립 니 다.
        본 프로그램 은 캡 처 를 다음 과 같이 실행 합 니 다.왼쪽 은 하나의 스 레 드 를 열 어 읽 고 그림 을 그립 니 다.오른쪽 은 두 개의 스 레 드 를 엽 니 다.하 나 는 그림 을 읽 고 하 나 는 그림 을 전문 적 으로 그립 니 다.
 
비교 해 보면 오른쪽 애니메이션 의 프레임 속 도 는 왼쪽 보다 현저히 빠 르 고 좌우 둘 다 Thread.sleep()를 사용 하지 않 았 습 니 다.왜 두 개의 스 레 드 를 열 고 한 사람 은 그림 을 읽 어야 합 니까?두 개의 스 레 드 를 열지 않 고 왼쪽 처럼 모두'읽 으 면서 그리 기'를 해 야 합 니까?Surface View 는 그림 을 그 릴 때마다 Canvas 를 잠 그 기 때 문 입 니 다.즉,같은 구역 을 이번에 다 그리 지 못 하면 다음 에 그 릴 수 없 기 때문에 애니메이션 재생 의 효율 을 높이 려 면 스 레 드 를 열 어 그림 을 전문 적 으로 그리고 다른 스 레 드 를 열 어 예비 처 리 를 해 야 합 니 다.
main.xml 소스 코드:

<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 android:id="@+id/Button02" android:layout_width="wrap_content" 
            android:layout_height="wrap_content" android:text="      ">
    
    <surfaceview android:id="@+id/SurfaceView01" 
        android:layout_width="fill_parent" android:layout_height="fill_parent">

본 프로그램의 원본 코드:

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 {
    /** Called when the activity is first created. */
    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;
            }
        }
    };
}
이상 은 본 고의 모든 내용 입 니 다.여러분 이 안 드 로 이 드 소프트웨어 프로 그래 밍 을 배 우 는 데 도움 이 되 기 를 바 랍 니 다.

좋은 웹페이지 즐겨찾기