配置更改后忽略view.invalidate()

时间:2012-12-13 11:38:59

标签: android android-view android-configchanges

使用SO解决我的问题一年后,我遇到了一个我无法找到解决方案的问题。

我使用多个线程来计算位图。当计算新的位图行时,我更新自定义视图并调用invalidate()。但是当我旋转手机时,位图会停止更新。在另一个屏幕旋转后,View仅更新一次,同时也可以看到在此期间计算的部分位图。

onCreate方法的一部分:

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

我使用handler来更新我的观点:

        public void handleMessage(final Message msg) {

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

在我看来,我使用:

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

解决方案

到目前为止,我找到了一个解决方案。如果我将invalidate()添加到onDraw的末尾,则会在屏幕方向更改后对位图进行核心更新(逐行)。我不认为这是非常“干净”的解决方案,所以我想了解为什么在配置更改后忽略来自invalidate()的{​​{1}}被调用?

谢谢!

1 个答案:

答案 0 :(得分:1)

我找到了解决方案。

问题在于Handler,这不是静态的。我忽略了“泄漏可能发生”的警告,因为我没有发布长时间延迟的消息。错误很大,因为配置更改后Handler无法以某种方式无法访问View。

这是解决方案:

    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

    }

}

底线:使用静态处理程序,如here

所述