使用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}}被调用?
谢谢!
答案 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
所述