2

次のプログラムは、行while (!done)(および閉じ括弧) のコメントを外さない限り機能しません。

なぜだか分かりますか?スレッドに描画コードを 1 回だけ実行するように要求できないのはなぜですか?

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {

    private SurfaceHolder holder;
    private MyThread myThread;
    private boolean hasSurface;

    protected float x, y;
    protected Paint paint;

    public MySurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);

        holder = getHolder();
        holder.addCallback(this);
        hasSurface = false;

        paint = new Paint(Paint.ANTI_ALIAS_FLAG|Paint.SUBPIXEL_TEXT_FLAG);
        paint.setColor(Color.RED);
    }

    public void resume() {
        if (myThread == null) {
            myThread = new MyThread();

            if (hasSurface == true)
                myThread.start();
        }
    }

    public void pause() {
        if (myThread != null) {
            myThread.requestExitAndWait();
            myThread = null;
        }
    }

    public void surfaceCreated(SurfaceHolder holder) {
        hasSurface = true;
        if (myThread != null)
            myThread.start();
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        hasSurface = false;
        pause();
    }

    public void surfaceChanged(SurfaceHolder holder, int format,
                               int w, int h) {
        if (myThread != null)
            myThread.onWindowResize(w, h);
    }

    @Override public boolean onTouchEvent(MotionEvent event) {
        x = event.getX();
        y = event.getY();
        postInvalidate();
        return true;
    }

    //************************************************
    class MyThread extends Thread {
        private int width, height;

        private boolean done;

        MyThread() {
            super();
            done = false;
        }

        @Override
        public void run() {
            SurfaceHolder surfaceHolder = holder;

            // while (!done) { --- We wish to update just once.

                Canvas canvas = surfaceHolder.lockCanvas();

                canvas.drawARGB(255, 0, 0, 128);
                canvas.drawCircle(x, y, 5.0f, paint);

                surfaceHolder.unlockCanvasAndPost(canvas);
                }
            // }
        }

        public void requestExitAndWait() {
            done = true;
            try {
                join();
            } catch (InterruptedException ex) { }
        }

        public void onWindowResize(int w, int h) {
            width = w;
            height = h;
        }
    }
}

アクティビティは次のとおりです。

public class MyActivity extends Activity {

    MySurfaceView mySurfaceView;

    @Override public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mySurfaceView = (MySurfaceView) findViewById(R.id.mySurfaceView);
    }

    @Override protected void onResume() {
        super.onResume();
        mySurfaceView.resume();
    }

    @Override protected void onPause() {
        super.onPause();
        mySurfaceView.pause();
    }
}

..そしてここにレイアウトがあります

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent">
   <.MySurfaceView
       android:id="@+id/mySurfaceView"
       android:layout_width="fill_parent"
       android:layout_height="fill_parent"/>
</FrameLayout>
4

1 に答える 1

2

どうぞ

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {

    ...

    class MyThread extends Thread {

        boolean update = false;

        @Override
        public void run() {
            SurfaceHolder surfaceHolder = holder;

            while (!done) {

                if(update) {
                    Canvas canvas = surfaceHolder.lockCanvas();

                    canvas.drawARGB(255, 0, 0, 128);
                    canvas.drawCircle(x, y, 5.0f, paint);

                    surfaceHolder.unlockCanvasAndPost(canvas);
                    update = false;
                }
            }
        }
    }

    public void requestUpdate() {
        update = true;
    }
}

何かが変更されるたびに、 requestUpdate(); を呼び出すだけです。

于 2013-08-14T22:04:53.547 に答える