android-maps-compose: java.lang.IllegalArgumentException: Unmanaged descriptor

This bug wasn’t solved. Got it today. Just use a lot of markers in clustering - wait for them to start show on the map and then switch screens (navigate) before all of them became rendered.

 java.lang.IllegalArgumentException: Unmanaged descriptor
  at com.google.maps.api.android.lib6.common.m.b(:com.google.android.gms.dynamite_mapsdynamite@233414047@23.34.14 (190800-0):10)
  at com.google.maps.api.android.lib6.impl.w.c(:com.google.android.gms.dynamite_mapsdynamite@233414047@23.34.14 (190800-0):18)
  at com.google.maps.api.android.lib6.impl.cw.u(:com.google.android.gms.dynamite_mapsdynamite@233414047@23.34.14 (190800-0):11)
  at com.google.android.gms.maps.model.internal.p.bb(:com.google.android.gms.dynamite_mapsdynamite@233414047@23.34.14 (190800-0):347)
  at m.fi.onTransact(:com.google.android.gms.dynamite_mapsdynamite@233414047@23.34.14 (190800-0):21)
  at android.os.Binder.transact(Binder.java:1164)
  at com.google.android.gms.internal.maps.zza.zzc(com.google.android.gms:play-services-maps@@18.1.0:2)
  at com.google.android.gms.internal.maps.zzy.zzs(com.google.android.gms:play-services-maps@@18.1.0:3)
  at com.google.android.gms.maps.model.Marker.setIcon(com.google.android.gms:play-services-maps@@18.1.0:2)
  at com.google.maps.android.clustering.view.DefaultClusterRenderer.onClusterUpdated(DefaultClusterRenderer.java:937)
  at com.google.maps.android.clustering.view.DefaultClusterRenderer$CreateMarkerTask.perform(DefaultClusterRenderer.java:1053)
  at com.google.maps.android.clustering.view.DefaultClusterRenderer$CreateMarkerTask.access$2300(DefaultClusterRenderer.java:992)
  at com.google.maps.android.clustering.view.DefaultClusterRenderer$MarkerModifier.performNextTask(DefaultClusterRenderer.java:707)
  at com.google.maps.android.clustering.view.DefaultClusterRenderer$MarkerModifier.handleMessage(DefaultClusterRenderer.java:678)
  at android.os.Handler.dispatchMessage(Handler.java:106)
  at android.os.Looper.loopOnce(Looper.java:201)
  at android.os.Looper.loop(Looper.java:288)
  at android.app.ActivityThread.main(ActivityThread.java:7872)
  at java.lang.reflect.Method.invoke(Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

Code:

    val events by viewModel.eventsLocalDto.filtered.collectAsStateWithLifecycle()
    val selectedEvent by viewModel.selectedEvent.collectAsStateWithLifecycle()

    Clustering(
        items = events,
        onClusterItemClick = {
            Timber.v("Marker clicked: ${it.name}")
            viewModel.selectEvent(it)
            true
        },
    )

    if (selectedEvent is EventItem) (selectedEvent as EventItem).latLng.let {
        val selectedMarker = BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)
        Marker(state = MarkerState(it), zIndex = 0.5f, icon = selectedMarker)
    }

selectedEvent wasn’t even used here. So, all markers had default view and their count was: 32632.

About this issue

  • Original URL
  • State: closed
  • Created 9 months ago
  • Reactions: 2
  • Comments: 17 (2 by maintainers)

Most upvoted comments

Hi folks,

The following PR might fix this issue. The Clustering was not being disposed, so probably with a large number of markers the process to deal with items in a cluster could be somehow taking longer, and by the time an item is going to be updated the map does not longer exist. I will let you know when it is merged and maybe you folks can take a look.

https://github.com/googlemaps/android-maps-compose/pull/458

I found the cause of the crash in my case:

val cameraPositionState = rememberCameraPositionState()
GoogleMap(
    modifier = Modifier.fillMaxSize(),
    cameraPositionState = cameraPositionState,
) {
    Clustering(
        items = items,
        clusterItemContent = { mapDataClass ->
            ClusterItemContent(
                mapDataClass = mapDataClass,
                isCameraMoving = cameraPositionState.isMoving,
            )
        },
    )
}

Looks like cameraPositionState changes when the screen is already leaving composition. Without using cameraPositionState for clusterItemContent, the app won’t crash.

I even found a workaround: var isScreenClosing by remember { mutableStateOf(false) } I set this boolean to true before navigating. Then I updated clusterItemContent:

clusterItemContent = { mapDataClass ->
    if (!isScreenClosing) {
        ClusterItemContent(
            mapDataClass = mapDataClass,
            isCameraMoving = cameraPositionState.isMoving,
        )
    }
},

With this I wasn’t able to replicate the crash anymore.

Anyway, I’m not 100% confident with this workaround. It doesn’t cover scenarios when navigation changes outside of the screen with map.

Proper fix should be that this library shouldn’t try to update marker icons while it’s being released.

Just tested with the latest release 3.0.0 and the issue is still there.

I have the same issue and it’s easy to reproduce. I have 200+ markers. By quickly tapping on the 200+ circle, map zooms in low res. Before it renders high res map and draw all markers, I navigate back to the previous screen. Within a second app crashes with the mentioned error.