简体   繁体   中英

How to draw on Canvas using multi-threading?

I have been developing the application for drawing, and there is the following code for it:

public class PainterView extends View implements DrawingListener {

private Context context;
private Painter painter;
private Bitmap background;
private Bitmap bitmap;
private Paint bitmapPaint;
private Path path;
private Paint paint;

private float x;
private float y;

public PainterView(Context context, Painter painter) {

    super(context);
    this.context = context;
    this.painter = painter;
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
}

@Override
protected void onDraw(Canvas canvas) {
    if (bitmap != null) {
        canvas.drawBitmap(background, 0, 0, bitmapPaint);
        canvas.drawBitmap(bitmap, 0, 0, bitmapPaint);
        canvas.drawPath(path, paint);
    }
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    x = event.getX();
    y = event.getY();
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        painter.touchStart(x, y);
        break;
    case MotionEvent.ACTION_MOVE:
        painter.touchMove(x, y);
        break;
    case MotionEvent.ACTION_UP:
        painter.touchUp();
        break;
    }
    return true;
}

@Override
public void onPictureUpdate(Bitmap background, Bitmap bitmap, Paint bitmapPaint, Path path, Paint paint) {
    this.background=background;
    this.bitmap = bitmap;
    this.bitmapPaint = bitmapPaint;
    this.path = path;
    this.paint = paint;
    invalidate();
}

public void setPainter(Painter painter) {
    this.painter = painter;
}
}

This code catches all touch event, send this event to model, this save coordinates and send bitmap to view for drawing.

I'm using this code, and it is working good, but my client tells me that drawing is not smooth breaks or missing at some places. So I need to use multithreading for it. So, please, tell me, how I can do it? Or may I increase the productivity using another way?

Here's a basic skeleton of how I implemented what you want:

public class Drawing extends Activity implements OnTouchListener{

    DrawPanel dp;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        dp = new DrawPanel(this);
        dp.setOnTouchListener(this);
            // do other stuff you want
            setContentView(dp);
    }

    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        dp.pause();
    }



    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        dp.resume();
    }

    public class DrawPanel extends SurfaceView implements Runnable{

        Thread t = null;
        SurfaceHolder holder;
        boolean isItOk = false ;

        public DrawPanel(Context context) {
            super(context);
            // TODO Auto-generated constructor stub
            holder = getHolder();
        }

        @Override
        public void run() {
            // TODO Auto-generated method stub
            while( isItOk == true){

                if(!holder.getSurface().isValid()){
                    continue;
                }

                Canvas c = holder.lockCanvas();
                c.drawARGB(255, 0, 0, 0);
                onDraw(c);
                holder.unlockCanvasAndPost(c);
            }
        }

        @Override
        protected void onDraw(Canvas canvas) {
            // TODO Auto-generated method stub
            super.onDraw(canvas);
                    // do your drawing stuff here
            }
        }

        public void pause(){
            isItOk = false;
            while(true){
                try{
                    t.join();
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
                break;
            }
            t = null;
        }

        public void resume(){
            isItOk = true;  
            t = new Thread(this);
            t.start();

        }




    }


    @Override
    public boolean onTouch(View v, MotionEvent me) {
    // capture your coordinates here         
    return true;

    }


}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM