0

I'm experimenting with the SurfaceView in Android and I'm trying to create a simple drawing type application, where you "draw" by touch on it. I have a thread running to handle the drawing onto the canvas but I'm hitting some performance issues. I read on http://developer.android.com/guide/topics/graphics/index.html that you need to repaint the entire surface so I tried storing all the touched points in a float array mPoints and than redraw them every time. Problem is when a lot of points build up it gets really slow. Here is the code for that:

    @Override
    public void run() { 

        while(mIsRunning) {
            Canvas c = null;
            try {                   
                c = mSurface.lockCanvas(null);
                synchronized(mSurface) {
                    int size = mPoints.getSize();
                    for(int i = 0; i < size; i += 2) {
                        c.drawCircle(mPoints.get(i), mPoints.get(i + 1), 3, mPaint);                            
                    }   
                }                                   
            }
            finally {
                if (c != null)
                    mSurface.unlockCanvasAndPost(c);
            }       

        }   
    }

However when I updated it so that it cleared the float array and only drew new touched points it causes a lot of flickering. From what I can tell this is because Android uses double buffering. I'm not sure how to get around these problems.

Corey Sunwold
  • 10,194
  • 6
  • 51
  • 55

2 Answers2

1

try writing to a bitmap and then redrawing the bitmap every time. You can maybe keep a record of last 10 points or something to allow undo etc.

Adil
  • 123
  • 1
  • 9
1

Building on Adil's answer, this is what I came up with and seems to work. It doesn't seem to quite pick up every single point if you try and draw a continuous line of points so it needs some further optimization but it does get the job done:

    @Override
    public void run() {
        mDrawing = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);       
        Canvas tempCanvas = new Canvas();
        tempCanvas.setBitmap(mDrawing);

        Canvas c = null;
        while(mIsRunning) {
            int size = mPoints.getSize();
            for(int i = 0; i < size; i += 2) {
                tempCanvas.drawCircle(mPoints.get(i), mPoints.get(i + 1), 3, mPaint);                           
            }    

            mPoints.empty();

            try {                   
                c = mSurface.lockCanvas(null);
                synchronized(mSurface) {
                    c.drawBitmap(mDrawing, 0, 0, mPaint);
                }                                   
            }
            finally {
                if (c != null)
                    mSurface.unlockCanvasAndPost(c);
            }       

        }   
    }
Corey Sunwold
  • 10,194
  • 6
  • 51
  • 55