3

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

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

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()我认为这不是非常“干净”的解决方案,所以我想了解为什么handler在配置更改后被忽略?

谢谢!

4

1 回答 1

1

我找到了解决方案。

问题出在处理程序中,它不是静态的。我忽略了“可能发生泄漏”警告,因为我没有发布长时间延迟的消息。大错特错,因为在配置更改之后 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

    }

}

底线:使用静态处理程序,如此处所述

于 2012-12-26T10:25:00.947 回答