0

尝试从我的 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();
}
4

2 回答 2

0

您确定在将新数据添加到 Itemized Overlay 后调用了 populate 吗?

祝你好运,路易斯

于 2012-07-19T02:26:21.240 回答
0

显然这个问题有点特定于我的代码。显然,android 缓存了要由回调处理的 mapView 的实例。当我的活动重新创建时,回调使用有效但未初始化的旧实例。

通过在重新创建 mapView 时取消所有活动的网络请求来解决

于 2012-07-30T21:29:53.623 回答