2012-12-13 25 views
3

在使用SO解决我的问题一年后,我遇到了一个我找不到解决方案的问题。配置更改后忽略view.invalidate()

我正在使用多个线程来计算位图。当计算新的位图行时,我更新自定义视图并调用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"); 
    } 

解决方案

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

谢谢!

+1

由于无效电话的onDraw你不应该调用内部的onDraw – Blackbelt

+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