canvas.DrawBitmap()在AsyncTask中执行atPostExecute但不显示位图

时间:2012-11-02 02:02:37

标签: android-asynctask ondraw

我正在呼叫invalidate(),呼叫onDraw()。运行doInBackGround()后,我希望在屏幕上显示的位图未显示。有人可以帮忙吗?

这是我到目前为止测试过的。

当我放置相同的代码行时

canvas.drawBitmap();
onPreExecute()中的

可行,但在onPostExecute()中,它不会显示预期结果。

这是我的代码:

public class FloorAppActivity extends Activity {
private Context globalContext;

private Point displaySize;
private int displayWidth;
private int displayHeight;

private String floorID;
private String floorName;
private String floorGridNumStr;
private int floorGridNum;
private String floorNumStr;
private int positionX;
private int positionY;
private int XCoord;
private int YCoord;
private int ZCoord;
private float signalStr;
private Integer dBm;

private Bitmap floorPlan;
private Bitmap userMark;
private Bitmap redPin;

private FloorView floorView;
private Connection conn = null;

private Canvas canvas=null;
private int newScrollRectX=0;
private int newScrollRectY=0;
private Paint paint;
private boolean a = false;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    globalContext = this;

    floorID = getIntent().getStringExtra("floorID");
    floorName = getIntent().getStringExtra("floorName");
    positionX = getIntent().getIntExtra("userPositionX",-1);
    positionY = getIntent().getIntExtra("userPositionY",-1);
    dBm = getIntent().getIntExtra("BestSignal", -1);
    //Get the grid number
    if(Integer.parseInt(floorName.substring(floorName.lastIndexOf("_")+1))<10)
        floorGridNumStr = floorName.substring(8, 9);
    else
        floorGridNumStr = floorName.substring(8, 10);
    floorGridNum = Integer.parseInt(floorGridNumStr);
    floorNumStr = floorName.substring(5,7);
    Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
    displaySize = new Point();

    try {
        // GetSize is not available in older models of Android
        display.getSize(displaySize);
    } catch (java.lang.NoSuchMethodError ignore) { // Older device
        displaySize.x = display.getWidth();
        displaySize.y = display.getHeight();
    }

    try {
        InputStream source = getAssets().open(floorID);
        floorPlan = BitmapFactory.decodeStream(source);

        displayWidth = Math.min(displaySize.x, floorPlan.getWidth());       
        displayHeight = Math.min(displaySize.y, floorPlan.getHeight());

        userMark = BitmapFactory.decodeResource(getResources(),R.drawable.star);
        redPin = BitmapFactory.decodeResource(getResources(),R.drawable.redpin);

        floorView = new FloorView(this);
        setContentView(floorView);
    } 
    catch (IOException e) {
        MapServerAPI server = new MapServerAPI(globalContext,"Retrieving floor plan. Please wait...") {
            @Override
            protected void onPostExecute(Bitmap bitmap) {
                super.onPostExecute(bitmap);

                if (bitmap == null)
                    Toast.makeText(globalContext, "Error in retrieving floor plan!", Toast.LENGTH_LONG).show();
                else {
                    floorPlan = bitmap;

                    displayWidth = Math.min(displaySize.x, floorPlan.getWidth());       
                    displayHeight = Math.min(displaySize.x, floorPlan.getHeight());

                    userMark = BitmapFactory.decodeResource(getResources(),R.drawable.star);
                    redPin = BitmapFactory.decodeResource(getResources(),R.drawable.redpin);

                    floorView = new FloorView(globalContext);
                    setContentView(floorView);
                }
            }
        };
        server.execute(floorID);
    }
}

@Override
public void onResume() {
    super.onResume();   
    registerReceiver(broadcastReceiver,new IntentFilter("FingerPrint_LOCATION_UPDATE"));
}

@Override
public void onPause() {
    super.onPause();
    unregisterReceiver(broadcastReceiver);
}

// listen for user location change
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String result = intent.getStringExtra("location");
        Toast.makeText(context,result,Toast.LENGTH_LONG).show();

        String floorId = intent.getStringExtra("floorID");
        floorName = intent.getStringExtra("name");
        dBm = intent.getIntExtra("BestSignal", -1);
        int userLocationX = intent.getIntExtra("userPositionX",-1);
        int userLocationY = intent.getIntExtra("userPositionY",-1);
        //Get the grid number
        if(Integer.parseInt(floorName.substring(floorName.lastIndexOf("_")+1))<10)
            floorGridNumStr = floorName.substring(8, 9);
        else
            floorGridNumStr = floorName.substring(8, 10);
        floorGridNum = Integer.parseInt(floorGridNumStr);
        floorNumStr = floorName.substring(5,7);
        if(!floorId.equals(floorID)){
            positionX = userLocationX;
            positionY = userLocationY;
            InputStream source=null;
            try {
                source = getAssets().open(floorID);
            } catch (IOException e) {

            }
            floorPlan = BitmapFactory.decodeStream(source);
            floorView.postInvalidate();
        }
    }
};
private class FloorView extends View {
    private Rect displayRect; //rect we display to
    private Rect scrollRect; //rect we scroll over our bitmap with

    private int scrollRectX = 0; //current left location of scroll rect
    private int scrollRectY = 0; //current top location of scroll rect
    private float scrollByX = 0; //x amount to scroll by
    private float scrollByY = 0; //y amount to scroll by
    private float startX = 0; //track x from one ACTION_MOVE to the next
    private float startY = 0; //track y from one ACTION_MOVE to the next

    public FloorView(Context context) {
        super(context);

        // Destination rect for our main canvas draw. It never changes.
        displayRect = new Rect(0, 0, displayWidth, displayHeight);
        // Scroll rect: this will be used to 'scroll around' over the 
        // bitmap in memory.
        if (positionX + displayWidth / 2 > floorPlan.getWidth()) 
            scrollRectX = floorPlan.getWidth() - displayWidth;
        else 
            scrollRectX = positionX - displayWidth / 2;
        if (scrollRectX < 0)
            scrollRectX = 0;

        if (positionY + displayHeight / 2 > floorPlan.getHeight()) 
            scrollRectY = floorPlan.getHeight() - displayHeight;
        else 
            scrollRectY = positionY - displayHeight / 2;
        if (scrollRectY < 0)
            scrollRectY = 0;

        scrollRect = new Rect(scrollRectX, scrollRectY, displayWidth, displayHeight);
    }



    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // Remember our initial down event location.
                startX = event.getRawX();
                startY = event.getRawY();
                break;

            case MotionEvent.ACTION_MOVE:
                float x = event.getRawX();
                float y = event.getRawY();
                // Calculate move update. This will happen many times
                // during the course of a single movement gesture.
                scrollByX = x - startX; //move update x increment
                scrollByY = y - startY; //move update y increment
                startX = x; //reset initial values to latest
                startY = y;
                invalidate(); //force a redraw
                break;
        }
        return true; //done with this event so consume it
    }

    @Override
    protected void onDraw(Canvas canvas1) {

        canvas=canvas1;
        // Our move updates are calculated in ACTION_MOVE in the opposite direction
        // from how we want to move the scroll rect. Think of this as dragging to
        // the left being the same as sliding the scroll rect to the right.
        newScrollRectX = scrollRectX - (int)scrollByX;
        newScrollRectY = scrollRectY - (int)scrollByY;

        // Don't scroll off the left or right edges of the bitmap.
        if (newScrollRectX < 0)
            newScrollRectX = 0;
        else if (newScrollRectX > (floorPlan.getWidth() - displayWidth))
            newScrollRectX = (floorPlan.getWidth() - displayWidth);

        // Don't scroll off the top or bottom edges of the bitmap.
        if (newScrollRectY < 0)
            newScrollRectY = 0;
        else if (newScrollRectY > (floorPlan.getHeight() - displayHeight))
            newScrollRectY = (floorPlan.getHeight() - displayHeight);

        // We have our updated scroll rect coordinates, set them and draw.
        scrollRect.set(newScrollRectX, newScrollRectY, 
            newScrollRectX + displayWidth, newScrollRectY + displayHeight);
        paint = new Paint();
        canvas.drawBitmap(floorPlan, scrollRect, displayRect, paint);

        // Update user position
        if (positionX >= newScrollRectX && positionX - newScrollRectX <= displayWidth
                && positionY >= newScrollRectY && positionY - newScrollRectY <= displayHeight)
            canvas.drawBitmap(userMark,positionX-newScrollRectX-userMark.getWidth()/2,positionY-newScrollRectY-userMark.getHeight()/2,paint);


        class AsyncTaskToConnect extends AsyncTask <Void, Void, Void>{      
            @Override
            protected Void doInBackground(Void... cmd) {
                // connect to database and retrieve values
                return null;
            }
            @Override
            protected void onPostExecute(Void v) 
            {//PE
                if (positionX >= newScrollRectX && positionX - newScrollRectX <= displayWidth
                        && positionY >= newScrollRectY && positionY - newScrollRectY <= displayHeight)
                {
                    canvas.drawBitmap(redPin,480-newScrollRectX-userMark.getWidth()/2,90-newScrollRectY-userMark.getHeight()/2,paint);
                }

                    //return null;
                    // Reset current scroll coordinates to reflect the latest updates, 
                    // so we can repeat this update process.
                    scrollRectX = newScrollRectX;
                    scrollRectY = newScrollRectY;
            }//PE       
        }
        AsyncTaskToConnect[] asyncTaskC = null;
        asyncTaskC = new AsyncTaskToConnect[1];
        asyncTaskC[0] = new AsyncTaskToConnect();           
        asyncTaskC[0].executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);    
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        // Cache our new dimensions; we'll need them for drawing.
        displayWidth = Math.min(w, floorPlan.getWidth());       
        displayHeight = Math.min(h, floorPlan.getHeight());

        // Destination rect for our main canvas draw.
        displayRect = new Rect(0, 0, displayWidth, displayHeight);
        // Scroll rect: this will be used to 'scroll around' over the
        // bitmap in memory.
        if (positionX + displayWidth / 2 > floorPlan.getWidth()) 
            scrollRectX = floorPlan.getWidth() - displayWidth;
        else 
            scrollRectX = positionX - displayWidth / 2;
        if (scrollRectX < 0)
            scrollRectX = 0;

        if (positionY + displayHeight / 2 > floorPlan.getHeight()) 
            scrollRectY = floorPlan.getHeight() - displayHeight;
        else 
            scrollRectY = positionY - displayHeight / 2;
        if (scrollRectY < 0)
            scrollRectY = 0;
        scrollRect = new Rect(scrollRectX, scrollRectY, displayWidth, displayHeight);

        super.onSizeChanged(w, h, oldw, oldh);
    }
}
}

P.S。这是我第一次发帖。如果我在帖子中犯了错误,请原谅我。感谢。

1 个答案:

答案 0 :(得分:0)

我认为问题在于您存储了传递到Canvas方法的onDraw对象。 onDraw方法返回后,该对象可能无效。

看起来您正在尝试在后台线程上准备Bitmap,然后在准备好时在屏幕上绘制它。您这样做的方法是 - 准备Bitmap,然后只需invalidate方法View上的onPostExecute。然后在onDraw方法中,您可以使用Bitmap对象并使用canvas.drawBitmap

绘制它