【问题标题】:NullPointer Exception on Android Google Maps while updating Map更新地图时 Android Google 地图上的 NullPointer 异常
【发布时间】:2013-06-30 21:44:15
【问题描述】:

我最近在我的应用程序中加入了ACRA,其中包括一个GoogleMapSupportFragment。我现在收到一些崩溃报告,我无法在我的设备上重现这些报告。如果我想在地图上放置新标记,应用程序会崩溃。每个标记都与一个位置相关联,该位置具有更多信息(地址、名称……)。

这是我管理GoogleMap的班级

public SignManager(MainActivity activity, GoogleMap map) {
    mActivity = activity;
    this.mMap = map;

    initMap();
}


private void initMap() {
    mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
    mMap.setMyLocationEnabled(true);
    //...
}

这是函数,它(有时)抛出NullPointerException。函数updateSignsInView 是从LocalBroadcastAsyncTasks 调用的,它从服务器接收带有新Markers 的更新。

public void updateSignsInView(LocationWO[] mSignArray) {

    if(mSignArray == null){
        Log.e(DEBUG_TAG,"updateSignsInView() -> mSignArray null");
        return;
    }

    resetMap();  //delete some unneeded data and do mMap.clear()

    mMarkerLocationMap = new HashMap<Marker, LocationWO>();

    for (int i = 0; i < mSignArray.length; i++) {

        //!!! this is the bad line: SignManager.java:101  
        Marker marker = mMap.addMarker(createMapMarker(mSignArray[i])); 

        mMarkerLocationMap.put(marker, mSignArray[i]);
    }

}


 //create a new Marker with given information
 private MarkerOptions createMapMarker(LocationWO mLocation) {

    MarkerOptions mMarker = new MarkerOptions()
    .position(
        new LatLng(mLocation.getmLatitude(), mLocation
            .getmLongitude()))
    .title(mLocation.getmName()
            .icon(BitmapDescriptorFactory.fromBitmap(icon));

    return mMarker;
}

这是我收到的 LogCat:

USER_COMMENT=null
ANDROID_VERSION=4.1.1
APP_VERSION_NAME=0.9
BRAND=htc_europe
PHONE_MODEL=HTC One X
CUSTOM_DATA=
STACK_TRACE=java.lang.NullPointerException
at maps.aj.bk.a(Unknown Source)
at maps.aj.bk.a(Unknown Source)
at maps.aj.al.a(Unknown Source)
at bcn.onTransact(SourceFile:167)
at android.os.Binder.transact(Binder.java:326)
at com.google.android.gms.maps.internal.IGoogleMapDelegate$a$a.addMarker(Unknown Source)
at com.google.android.gms.maps.GoogleMap.addMarker(Unknown Source)
at MYAPP.SignManager.updateSignsInView(SignManager.java:101)
at MYAPP.MainActivity$1.onReceive(MainActivity.java:389)
at android.support.v4.content.LocalBroadcastManager.executePendingBroadcasts(LocalBroadcastManager.java:297)
at android.support.v4.content.LocalBroadcastManager.access$000(LocalBroadcastManager.java:46)
at android.support.v4.content.LocalBroadcastManager$1.handleMessage(LocalBroadcastManager.java:116)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:155)
at android.app.ActivityThread.main(ActivityThread.java:5493)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:795)
at dalvik.system.NativeStart.main(Native Method)

我有 99.9% 的把握,mMap 不可能是 null。 mMap 在 onCreate() 方法中设置。

有人有什么想法吗?

编辑:setupMap 函数

private void setUpMapIfNeeded() {

    if (mMap == null) {
        mMap = ((SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map_screen)).getMap();

        if (mMap != null) {
            setUpMap();
        }
    }
}

【问题讨论】:

  • BitmapDescriptorFactory.fromBitmap(icon) 中的icon 是什么?你在哪里初始化它?
  • 嗯...好点。 icon 在 appstart 上加载(来自互联网),并且对 icon 的引用存储在 LocationWO-Model 中。但是如果Bitmap-Iconnull,它不应该在createMarker() 方法中崩溃吗?还是以后会崩溃,因为地图上没有icon tp地点?

标签: android google-maps nullpointerexception


【解决方案1】:

这里的问题是icon传递的是null

但是如果 Bitmap-Icon 为空,它不应该在 createMarker() 方法中崩溃吗?还是以后会崩溃,因为地图上没有图标tp地点?

是的,如果它直接在GoogleMap.addMarkerBitmapDescriptorFactory.fromBitmap 内抛出 NPE 会更好,但它不会发生在你的 createMapMarker 内,除非你在 icon 上调用方法。

无法说出为什么是null,因为问题中没有相关代码,但我怀疑该进程在用户离开应用程序时被杀死,然后在他们返回时重新创建。

【讨论】:

  • 您好 macie,感谢您的回答! icon 应在返回时重新创建。我有一个检查方法isAppInitialized(),它正在重新加载图标。我手动将MarkerOption 中的icon 设置为null,它正在加载谷歌地图标准图标。您的意思是该进程会杀死下载的图像,但不会杀死LocationWO 中的图标引用吗?
  • LocationWO 是否包含对icon: Bitmap 的引用?从代码看来,icon 是字段或静态引用。您可能想要更新它并添加初始化icon 的相关代码。如果您致电MarkerOptions.icon(null),它应该可以工作。但如果你打电话给MarkerOptions.icon(BitmapDescriptorFactory.fromBitmap(null)) 不应该。
  • 是的!我可以重现错误。多谢!还不知道,为什么icons 得到null,但我们明天再看
【解决方案2】:

长时间不使用或操作系统需要内存时,Android 会破坏您的应用。 如果您将MarkerOptions 保存在onSaveInstanceState 中,以便稍后尝试重新创建Marker,请注意Marker 的图标不是Parcelable,因此不会保存。您需要将独立图标另存为Bitmap,即Parcelable,并在重新创建标记时执行addMarker(savedMarkerOptions.icon(bitmap));

【讨论】:

    【解决方案3】:

    一种可能性是,当您的 asynctask 运行时发生方向更改时,mMap 在某些情况下会变为 null。在这种情况下,当调用updateSignsInView 时,mMap 尚未设置,因此您在Marker marker = mMap.addMarker(createMapMarker(mSignArray[i])); 行获得一个空指针对于在此行之前调用的resetMap();,可能对mMap 和因此没有错误。

    【讨论】:

    • 嗨,托尼,我的应用程序仅在纵向模式下运行。我也考虑过另一个空检查,但仍然很高兴找到真正的问题。 (我无法重现错误)
    【解决方案4】:

    您是否将地图连接到 xml 文件中的 Fragment?例如 mmap=findViewbyId(R.id.map); ?

    【讨论】:

    • 是的,我做到了。我刚刚更新了我的答案。顺便说一句:该应用程序正在运行,因此错误不会每次都出现,只是有时..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多