use canvas.drawBitmap in AsyncTask onPostExecute

喜你入骨 提交于 2020-01-03 03:36:25

问题


i use async task to draw bitmap on view,but it's draw nothing!
this is the asynctask code

class BitmapWorker extends AsyncTask<String, Void, Void>
{

    private Canvas canvas;
    private Rect rcText;
    private Paint paint;
    private Options options;
    private Options opt;
    public BitmapWorker(Canvas canvas,Rect rcText,Paint paint)
    {
        this.canvas = canvas;
        this.rcText = rcText;//the bitmap must draw on it's rect
        this.paint = paint;
    }

    @Override
    protected Void doInBackground(String... params)
    {
        options = new Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(m_AttachSource, options);
        opt = new Options();
        opt.inPurgeable = true;
        opt.inSampleSize = calculateInSampleSize(options, INSAMPLESIZE_THIMBPIC_WIDTH, INSAMPLESIZE_THIMBPIC_HEIGHT);

        LoadThumbPic(m_AttachSource, opt);
        return null;
    }

    @Override
    protected void onPostExecute(Void result)
    {
        super.onPostExecute(result);
        Boolean hasBitmap = false;
        while(!hasBitmap)
        {
            if(m_PictureMessageTumbPic.get() != null)
            {
                canvas.drawBitmap(m_PictureMessageTumbPic.get(), null, rcText, paint);
                hasBitmap = true;
            }
            else
            {
                Options opt = new Options();
                opt.inPurgeable = true;
                opt.inSampleSize = calculateInSampleSize(options, INSAMPLESIZE_THIMBPIC_WIDTH, INSAMPLESIZE_THIMBPIC_HEIGHT);
                LoadThumbPic(m_AttachSource, opt);
                canvas.drawBitmap(m_PictureMessageTumbPic.get(), null, rcText, paint);
                hasBitmap = true;
            }
        }
    }
}

tnx 4 adv.


回答1:


You said that you are drawing to a view, but from your code, it appears that you have not invalidate the view after the drawing operation. So you have to modify the AsyncTask to take in the View, and call its invalidate() method after you've updated the Canvas.

Remember that modern OS caches graphics elements to improve performance, so you have to use the mechanism it provided to notify it that an update is in order.

Try this (have not run the code, may have silly errors):

class BitmapWorker extends AsyncTask<String, Void, Void>
{

    private Canvas canvas;
    private Rect rcText;
    private Paint paint;
    private Options options;
    private Options opt;
    private View view;
    public BitmapWorker(Canvas canvas,Rect rcText,Paint paint, View view)
    {
        this.canvas = canvas;
        this.rcText = rcText;//the bitmap must draw on it's rect
        this.paint = paint;
        this.view = view;
    }

    @Override
    protected Void doInBackground(String... params)
    {
        options = new Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(m_AttachSource, options);
        opt = new Options();
        opt.inPurgeable = true;
        opt.inSampleSize = calculateInSampleSize(options, INSAMPLESIZE_THIMBPIC_WIDTH, INSAMPLESIZE_THIMBPIC_HEIGHT);

        LoadThumbPic(m_AttachSource, opt);
        return null;
    }

    @Override
    protected void onPostExecute(Void result)
    {
        super.onPostExecute(result);
        Boolean hasBitmap = false;
        while(!hasBitmap)
        {
            if(m_PictureMessageTumbPic.get() != null)
            {
                canvas.drawBitmap(m_PictureMessageTumbPic.get(), null, rcText, paint);
                hasBitmap = true;
            }
            else
            {
                Options opt = new Options();
                opt.inPurgeable = true;
                opt.inSampleSize = calculateInSampleSize(options, INSAMPLESIZE_THIMBPIC_WIDTH, INSAMPLESIZE_THIMBPIC_HEIGHT);
                LoadThumbPic(m_AttachSource, opt);
                canvas.drawBitmap(m_PictureMessageTumbPic.get(), null, rcText, paint);
                hasBitmap = true;
            }
        }

        if(hasBitmap) {
            view.invalidate();
        }
    }
}



回答2:


Make this on your onPostExecute method:

  • Get the surface holder.
  • Initialise a Canvas from a Holder.
  • Make the holder unlock your canvas and post the canvas.
protected void onPostExecute(Bitmap result) {

    SurfaceHolder holder = getSurfaceHolder();
    Canvas canvas = null;

    try {
        canvas = holder.lockCanvas();
        if (canvas != null) {
            canvas.drawBitmap(result, 50, 50, paint);
        }

    } finally {
        if (canvas != null)
            holder.unlockCanvasAndPost(canvas);
    }
}


来源:https://stackoverflow.com/questions/17896546/use-canvas-drawbitmap-in-asynctask-onpostexecute

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!