3

after one year of using SO to solve my questions, I came to a problem for which I cannot find solution.

I am using multiple threads to calculate bitmap. When new row of bitmap is calculated, I update custom view and call invalidate(). But when I rotate my phone, bitmap stops updating. After another screen rotation View is updated only once, and part of bitmap that was calculated in the meantime is also visible.

part of onCreate method:

        view = (MyView) findViewById(R.id.view1);

    if (savedInstanceState != null)
    {
        bitmap = savedInstanceState.getParcelable("bitmap");
        view.bitmap = bitmap;
    }
    else
    {
        bitmap = Bitmap.createBitmap(400, 500, Bitmap.Config.ARGB_8888);
        bitmap.eraseColor(Color.GRAY);
        view.bitmap = bitmap;
    }

I use handler to update my view:

        public void handleMessage(final Message msg) {

        Log.i("Recieved", "redraw signal");
        view.bitmap = bitmap;
        view.invalidate();  
    }

In my view, i use:

       Bitmap bitmap;
   Rect rect;

   //...constructors

   @Override
   protected void onSizeChanged (int w, int h, int oldw, int oldh)
   {
       rect = new Rect(0, 0, getWidth(), getHeight());
   }

   @Override
   protected void onDraw(Canvas canvas)
   { 
       super.onDraw(canvas);
       if (bitmap!=null)
       {               
           canvas.drawBitmap(bitmap, null, rect, null);
       }
        Log.i("onDraw", "draw"); 
   }

Solution

So far, I have found one solution. If I add invalidate() to the end of onDraw, bitmap is corectly updated(row by row) after screen orientation change. I don't think this is very "clean" solution, so I would like to understand why is invalidate() called from handler ignored after config change?

Thanks!

D.D.
  • 154
  • 1
  • 5

1 Answers1

1

I found a solution.

Problem was in Handler, which was NOT static. I ignored "Leaks might occur" warning because I wasn't posting long delayed messages. Big mistake, because after configuration change Handler was somehow unable to reach View.

Here is solution:

    static class MyHandler extends Handler {
    private final WeakReference<MainActivity> mTarget;

    public MyHandler(MainActivity target) {
        mTarget = new WeakReference<MainActivity>(target);

    }

    @Override
    public void handleMessage(Message msg) {
         MainActivity target = mTarget.get();
...other stuff...
        target.view.invalidate(); // now this works after configuration change

    }

}

Bottom line: use static handler, as explained here

Community
  • 1
  • 1
D.D.
  • 154
  • 1
  • 5