2012-11-02 51 views
2

我打电话给invalidate(),它调用onDraw()。我希望在屏幕上显示的位图在运行doInBackGround()后未显示。谁能帮忙?canvas.DrawBitmap()在AsyncTask中的onPostExecute上执行,但不显示位图

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

当我把代码

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); 
    } 
} 
} 

附:这是我第一次发帖。请原谅我,如果我在我的帖子中犯了错误。谢谢。

回答

0

我认为问题在于你正在存储传入onDraw方法的Canvas对象。在onDraw方法返回后,该对象可能无效。

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

+0

非常感谢您的回答。它帮助了很多人。虽然这确实在我脑海中,但我通过做“canvas = canvas1”来解释这个问题。再次感谢你 – user1793052

相关问题