问题
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