Osmdroid试图在Fragment.onStart()过程中重新绘制已删除的多边形



所以我一直在开发一个应用程序,其中包含了osmdroid的地图视图,每当多边形保存到我的房间数据库中时,我都会使用LiveData在其中绘制一个(新的(多边形。现在,当用地图来回循环进入片段时,地图试图";draw";不应该再存在的多边形。令人惊讶的是,这个多边形有其私有属性mOutline == null,因此当片段试图将其添加到地图时,会抛出一个NullPointerException。它不在我的数据库中,因为我在Fragment.onViewCreated()期间清除了它,在那里我还从地图上删除了所有覆盖…:

//in onViewCreated of my Fragment:
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//...
OverlayManager overlayManager = view_binding.map.getOverlayManager();
overlayManager.removeAll(overlayManager.overlays());
view_model.clearPolygon() 
/* -> now the database is empty (I checked it!) and the 
* ViewModels.polygon value is set to null using postValue(null)
* this call also is executed in another thread, because I apparantly am not allowed to
*access my database on the main thread
*/
view_model.polygon.observe(getViewLifecycleOwner(), polygon -> {
// the null check is here because the Database->LiveData return 
// null after view_model.clearPolygon()
if (polygon != null) {
setPolygon(polygon);
}
});
//...
}
setPolygon(Polygon polygon) {
polygon.getFillPaint().setColor(Color.parseColor("#1EFFE70E"));
view_binding.map.getOverlayManager().add(polygon);
view_binding.map.invalidate();
IMapController mapController = view_binding.map.getController();
mapController.setCenter(polygon.getActualPoints().get(0));
mapController.setZoom(16.0);    
}

现在这一直工作到我使用我的";背面";按钮返回到上一个片段,并用地图重新输入片段,在那里我再次选择要绘制的多边形,将其写入数据库(之前已清除!(,然后片段再次从LiveData中绘制但是Fragment.onStart()期间,当数据库为空时,它首先尝试绘制这个没有轮廓的wierd多边形。我可以只捕获NullPointerException,但我认为我自己的代码中存在某种错误,这将是一个肮脏的解决方案。有线索吗?

编辑:忘记在代码部分完成注释

所以在发布这个问题后(当然是-_-(,我发现了一个不那么脏的修复程序:在我的ViewModel中,clearPolygon()方法看起来像这样:

clearPolygon() {
// with callback to post the null value to the private field
repository.clearPolygon(_polygon::postValue); 
}

我把它改成:

clearPolygon() {
_polygon.setValue(null);
// with callback to post the null value to the private field
repository.clearPolygon(_polygon::postValue);
}

现在问题消失了,并且最终存储库将是";真理的单一来源";再次(postValue一到(。我仍然觉得这不是一个完美的解决方案,因为ViewModel和Repository之间的短时间不一致,所以目前我不会将这个答案标记为已接受,以防有人提出更好的解决方案。。。

最新更新