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();
}