同一个Canvas中的多线程

时间:2012-03-30 00:11:50

标签: android multithreading canvas

好吧,我会试着解释一下我假装的内容:

我想根据触摸屏幕的坐标在画布中的随机位置绘制位图,我希望每次用户触摸屏幕时都会显示一条消息(文本)。

所以,如果在同一个线程中绘制文本而不是我对位图的绘制,它会立即出现并消失,我希望它在屏幕上停留几秒钟和消失。我的第一个想法是使用Thread.sleep(),但为此我必须只为文本创建一个线程,否则我也会搞乱Bitmap。

我一直在尝试在同一个画布中使用多线程,但我不知道如何。有人可以向我解释......

这是我到目前为止的一些代码:

private void init() {
        // CREATE SURFACEHOLDER AND ADD THIS CLASS AS HIS CALLBACK
        enemyHolder = getHolder();
        enemyHolder.addCallback(this);

        scoreHolder = getHolder();
        scoreHolder.addCallback(this);

        hasSurface = false;

    }

public void resume(){

        if (surfaceViewThread == null) {
            surfaceViewThread = new SurfaceViewThread(); // CREATE A NEW
                                                            // THREAD
            if (hasSurface)
                surfaceViewThread.start(); // START OUR THREAD
        }

        if (secondThread == null) {
            secondThread = new SecondThread();

            if (hasSurface)
                secondThread.start();
        }

    }



public void surfaceCreated(SurfaceHolder holder) {
        hasSurface = true;

        if (surfaceViewThread != null)
            surfaceViewThread.start();

        if (scoreShow == 1) {

            if (secondThread != null)
                secondThread.start();
        }
    }

// THREAD

    private final class SurfaceViewThread extends Thread {
        private boolean done;

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

        @Override
        public void run() {
            // TODO Auto-generated method stub
            super.run();
            SurfaceHolder surfaceHolder = enemyHolder;

            while (!done) {

                Canvas canvas = surfaceHolder.lockCanvas();

                canvas.drawColor(Color.WHITE);

                canvas.drawBitmap(enemy1, enemy1X, enemy1Y, null); // DRAW
                                                                    // FIRST
                                                                    // ENEMY




    // SECOND THREAD

    private final class SecondThread extends Thread {
        private boolean done;

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

        @Override
        public void run() {
            // TODO Auto-generated method stub
            super.run();
            SurfaceHolder surfaceHolder = scoreHolder;

            while (!done) {

                Canvas canvas = surfaceHolder.lockCanvas();

                Paint paint = new Paint();
                paint.setColor(Color.BLACK);

                canvas.drawText("xD", 50, 50, paint);

                surfaceHolder.unlockCanvasAndPost(canvas);

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                scoreShow = 0;

            }

        }

2 个答案:

答案 0 :(得分:1)

您需要使用SurfaceView吗?这似乎是一种艰苦的工作方式。

我刚刚通过创建自定义视图类并重写onDraw方法来完成类似的操作。然后使用canvas.save()和canvas.restore()。这是我的onDraw的相关部分。

@Override
public void onDraw(Canvas canvas) {

    canvas.save();

    // scale the canvas
    canvas.scale(scaleFactor, scaleFactor); //, mid.x, mid.y);

    // and translate...
    canvas.translate(translateX / scaleFactor, translateY / scaleFactor);

    super.onDraw(canvas);

    // draw the lights
    for(Light light:lights){
        if (light.isOn){
            canvas.drawCircle(light.getX(),light.getY(), light.getDiameter() / scaleFactor,light.paint);
        }
    }

    canvas.restore();
}

灯光在活动中通过一个单独的线程打开和关闭,该活动使视图膨胀。只要它们打开,它们就会留在屏幕上。

干杯

答案 1 :(得分:0)

这是一些不完整的伪代码,可以执行您所描述的操作。每个元素都有很多很好的例子可以帮助你填补空白。

public class MyCustomView extends View {

     int touchPointX;
     int touchPointY;

     private String mText;

     public MyCustomView(Context context) {

         // do initialisation stuff

     }

     public setText(String text){
         mText = text;
         this.invalidate();
     }

     @Override
     public void onDraw(Canvas canvas) {

        canvas.save();

        super.onDraw(canvas);

        canvas.drawBitmap(touchPointX, touchPointY, bitmap)

        if (!mText.equals(""){
            canvas.drawText(touchPointX, touchPointY + 10, mText)
        }

        canvas.restore();
    }

}

public class MyActivity extends Activity implements OnTouchListener{

     private Handler mHandler = new Handler(); 
     private MyCustomView mCustomView;

     @Override
     protected void onCreate(Bundle savedInstanceState) {
           mCustomView = (MyCustomView) findViewById(r.id.myCustomView);
     }

     @Override
    public boolean onTouch(View v, MotionEvent rawEvent) {

           // get x and y of touch
           mCustomview.touchPointX = x;
           mCustomview.touchPointY = y;
           mCustomView.setText("Screen touched");

           // clear the text after 5 seconds
           mHandler.postDelayed(clearText, 5000);


           // redraw the view
           mCustomView.invalidate();

    }

    private void clearText(){mCustomView.setText("");}

}