android-maps-utils: DefalutClusterRender crash sometimes in some Devices

Hi! I have in my app a painful error

image

image

I can´t reproduce this error, either in the emulators or in my physical devices. My app has 20% users with this crash about google maps

I have my app made in kotlin. Two days ago update to the last version maps-utils, but the error persists. Now I use this maps utils version com.google.maps.android:android-maps-utils:1.3.3

My DefaultClusterRender is

    override fun shouldRenderAsCluster(cluster: Cluster<T>): Boolean {
        return cluster!!.size >= 2
    }

    override fun onBeforeClusterItemRendered(item: T, markerOptions: MarkerOptions) {
        item?.let {item ->
            val  markerItem =  item as? ProfileClusterMarker
            markerItem?.let {
                markerOptions.icon(it.icon)
                markerOptions.title(it.title)
                markerOptions.title(it.snippet)

            }
        }
    }

In previous maps utils version, I had to override the method with the nullable property because always get any crash in my app (in the new version is not possible this)

//    override fun onBeforeClusterItemRendered(item: T?, markerOptions: MarkerOptions?) {
//        item?.let {item ->
//            val  markerItem =  item as? ProfileClusterMarker
//            markerItem?.let {
//                markerOptions?.icon(it.icon)
//                markerOptions?.title(it.title)
//                markerOptions?.title(it.snippet)
//
//            }
//        }
//
//    }

//    override fun onClusterItemUpdated(item: T, marker: Marker?) {
//        var changed = false
//        // Update marker text if the item text changed - same logic as adding marker in CreateMarkerTask.perform()
//        // Update marker text if the item text changed - same logic as adding marker in CreateMarkerTask.perform()
//        if (item!!.title != null && item!!.snippet != null) {
//            if (!item!!.title.equals(marker!!.title)) {
//                marker!!.title = item!!.title
//                changed = true
//            }
//            if (!item!!.snippet.equals(marker!!.snippet)) {
//                marker!!.snippet = item!!.snippet
//                changed = true
//            }
//        } else if (item!!.snippet != null && !item!!.snippet.equals(marker!!.title)) {
//            marker!!.title = item!!.snippet
//            changed = true
//        } else if (item!!.title != null && !item!!.title.equals(marker!!.title)) {
//            marker!!.title = item!!.title
//            changed = true
//        }
//        // Update marker position if the item changed position
//        // Update marker position if the item changed position
//        if (!marker!!.position.equals(item!!.position)) {
//            marker!!.position = item!!.position
//            changed = true
//        }
//        if (changed && marker!!.isInfoWindowShown) {
//            // Force a refresh of marker info window contents
//            marker!!.showInfoWindow()
//        }
//    }

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 2
  • Comments: 15 (9 by maintainers)

Most upvoted comments

@arriolac We were not able to reproduce this issue on our available devices but the order would be like this:

clusterManager.clearItems()
clusterManager.cluster()
map.clear()

We also don’t use a custom icon for cluster just the default. I think I’ll try to use the MarkerManager for clearing individual markers and calling remove() on individual polygons instead of GoogleMap.clear() as a workaround.

Hi, I got similar crash before. In my case, I used Fragment and added cluster items at onMapReady() and called map.clear() at onDestroyView(). However, there might be some case that onMapReady() is called after onDestroyView() and mCreateMarkerTasks in DefaultClusterRenderer still executes perform() which causes the crash.

Here, as a workaround, I have to check Fragment isAdded && !isRemoving && !isDetached && view != null at onMapReady() callback.

Hope this helps.

@arriolac It needs to stay, because as you say the contents of the cluster (and size) may have changed. The default implementation of onClusterUpdated() needs to match the default implementation of onBeforeClusterRendered() for the icons to always match the internal data model given the current caching implementation.

As you mentioned in https://github.com/googlemaps/android-maps-utils/issues/746#issuecomment-646211580, my guess is that the underlying issue here is that the call directly to GoogleMap.clear() is removing a marker that’s being managed/cached by the ClusterManager/Renderer, and then when the ClusterRenderer tries to update the state of that marker (here, update the icon) it throws this exception. So the workaround/solution would be to use the APIs on the ClusterManager and, if other markers are on the map, the MarkerManager rather than interacting with the GoogleMap directly.