0

MapView から現在のズーム レベルを取得しようとすると、非常に奇妙な NullPointerException が発生します。問題は、これが毎回ではなく、getZoomLevel()関数内のどこかで発生することです。この関数のソース コードを調査すると、これは単なる getter 関数であり、ここで NullPointerException が発生する可能性はないことがわかります。mapView 自体は、それが発生した時点で null ではなく、他の MapView インターフェイスへの呼び出し (正常に動作するなどgetProjection()) です。

私のコード構造の簡単な背景は次のとおりです。

一定量のアイテムを含むマップ ビューと ItemizedOverlay があります。新しいデータがある場合、互いに近いアイテムを結合する必要があります。機能するパラメータの 1 つcoalesce()は現在のズーム レベルで、理論的には MapView から取得できるはずです。

uiThread 内に呼び出しを配置し​​ようとしcoalesce()ましたが、それでも時々 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()));
    }
}

getZoomLevel()呼び出し時にのみ NullPointerException があることに注意してください。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

アイテム化されたオーバーレイに新しいデータを追加した後、populateを呼び出してもよろしいですか?

頑張って、ルイス

于 2012-07-19T02:26:21.240 に答える
0

どうやら問題は私のコードに少し特有のものです。どうやら、android は、コールバックによって処理される mapView のインスタンスをキャッシュします。そして、アクティビティが再作成されると、コールバックは有効であるが初期化された古いインスタンスを使用します。

mapView が再作成されたときにアクティブなネットワーク リクエストをすべてキャンセルすることで解決しました。

于 2012-07-30T21:29:53.623 に答える