尝试从我的 MapView 获取当前缩放级别时,我变得非常奇怪 NullPointerException。问题是这种情况并非每次都发生,而是发生在getZoomLevel()
函数内部的某个地方。调查此函数的源代码表明这只是一个 getter 函数,并且 NullPointerException 不应该在这里发生。mapView 本身在发生并调用其他 MapView 接口时不为空(例如getProjection()
工作正常)。
这是我的代码结构的简要背景:
我有一定数量的项目的地图视图和 ItemizedOverlay。当我有新数据时 - 我需要合并彼此接近的项目。起作用的参数之一coalesce()
是当前缩放级别,理论上我应该能够从我的 MapView 中获得。
我试图coalesce()
在 uiThread 内部进行调用,但有时我仍然会收到 NullPointerException。
我设法通过在我的自定义地图视图中跟踪最后一个已知的 zoomLevel 并在getZoomLevel
失败时返回它来解决这个问题:
public final int getCurrentZoomLevel()
{
try
{
return this.getZoomLevel();
} catch (Exception ex)
{
ex.printStackTrace();
return lastZoomLevel;
}
}
但是,我仍然很好奇它为什么会发生。它发生在不同的设备和不同的 Android 版本上。
这是堆栈跟踪:
07-18 11:31:22.435: W/System.err(8054): java.lang.NullPointerException
07-18 11:31:22.435: W/System.err(8054): at com.google.android.maps.MapView.getZoomLevel(MapView.java:1094)
07-18 11:31:22.435: W/System.err(8054): at com.inrix.lib.view.CustomMapView.getCurrentZoomLevel(CustomMapView.java:195)
07-18 11:31:22.435: W/System.err(8054): at com.inrix.lib.mapitems.incidents.IncidentMapItemOverlay.performCoalesceInternal(IncidentMapItemOverlay.java:109)
07-18 11:31:22.435: W/System.err(8054): at com.inrix.lib.mapitems.MapItemsOverlay$4.run(MapItemsOverlay.java:448)
07-18 11:31:22.435: W/System.err(8054): at java.lang.Thread.run(Thread.java:1096)
07-18 11:31:22.435: W/System.err(8054): at com.inrix.lib.mapitems.MapItemsOverlay.recoalesce(MapItemsOverlay.java:450)
07-18 11:31:22.442: W/System.err(8054): at com.inrix.lib.mapitems.MapItemsOverlay$2.run(MapItemsOverlay.java:281)
07-18 11:31:22.442: W/System.err(8054): at android.os.Handler.handleCallback(Handler.java:587)
07-18 11:31:22.442: W/System.err(8054): at android.os.Handler.dispatchMessage(Handler.java:92)
07-18 11:31:22.442: W/System.err(8054): at android.os.Looper.loop(Looper.java:123)
07-18 11:31:22.442: W/System.err(8054): at android.app.ActivityThread.main(ActivityThread.java:4627)
07-18 11:31:22.442: W/System.err(8054): at java.lang.reflect.Method.invokeNative(Native Method)
07-18 11:31:22.442: W/System.err(8054): at java.lang.reflect.Method.invoke(Method.java:521)
07-18 11:31:22.442: W/System.err(8054): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
07-18 11:31:22.442: W/System.err(8054): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
07-18 11:31:22.442: W/System.err(8054): at dalvik.system.NativeStart.main(Native Method)
调用coalesce
看起来像:
protected void performCoalesceInternal(IOnCoalesceCompleteListener callback)
{
if (callback != null)
{
callback.onCoalesceComplete(coalescer.coalesce(
mapItemsController.getRawItemsCollection(),
MapItemType.Incident,
mapView.getCurrentZoomLevel(),
mapView.getProjection()));
}
}
请注意,我有 NullPointerException 仅getZoomLevel()
随叫随到。mapView.getProjection()
工作正常。
活动创建/初始化阶段:
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
........
this.setContentView(R.layout.content_inrixmap_activity);
// Initialize map.
this.mapView = (CustomMapView) findViewById(R.id.map_view);
........
// Create overlays.
this.currentLocationOverlay = new CurrentLocationOverlay(this.mapView);
this.trafficTileOverlay = new TrafficTileOverlay(new TrafficTileManager(this, this.trafficTileHandler));
this.cameraOverlay = new CameraMapItemOverlay(this, this.mapView, this);
this.incidentsOverlay = new IncidentMapItemOverlay(this, this.mapView, this);
// Add overlays to map.
this.mapView.addOverlay(this.trafficTileOverlay);
this.mapView.addOverlay(this.currentLocationOverlay);
this.mapView.addOverlay(this.cameraOverlay);
this.mapView.addOverlay(this.incidentsOverlay);
this.mapView.preLoad();
}