fix(map): scope cluster-renderer ViewTreeLifecycleOwner to map host view#5708
Merged
Conversation
maps-compose renders each non-clustered item to a bitmap through an off-screen ComposeView attached under the MapView (ComposeUiClusterRenderer + NoDrawContainerView). That ComposeView walks the view tree for a ViewTreeLifecycleOwner and, finding none, crashes with "Composed into the View which doesn't propagate ViewTreeLifecycleOwner!" (googlemaps/android-maps-compose#875 / #325) — a FATAL on the map screen still present in 2.7.14 (29321006), i.e. after #5704. #5704 removed the prior workaround because it attached a transient NavEntry lifecycle to the activity root, causing the node-list popup 0x0 regression (#5684). Re-introduce owner propagation but scope it to LocalView.current (the map host view, an ancestor of the internal MapView) instead of view.rootView, and restore the previous owners on dispose so Popups and DropdownMenus are left untouched. Keep a Lifecycle.STARTED guard to skip the cluster renderer's async-Handler render after the screen has stopped. Clustering, clusterItemContent, and the precision-circle decoration are unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jun 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The top FATAL crash on the google flavor of 2.7.14 is
com.google.maps.android.compose.clustering.ComposeUiClusterRenderer.renderViewToBitmapDescriptor—IllegalStateException: Composed into the View which doesn't propagate ViewTreeLifecycleOwner!. It is still present in build 29321006, i.e. after #5704.maps-compose renders each non-clustered item to a bitmap through an off-screen
ComposeViewthat it attaches under theMapView(ComposeUiClusterRenderer+NoDrawContainerView). ThatComposeViewwalks up the view tree for aViewTreeLifecycleOwner; when it finds none it crashes. There is no upstream fix as of maps-compose 8.3.0 (latest) — tracked unresolved as googlemaps/android-maps-compose#875 / #325.#5704 removed the previous workaround because it attached a transient NavEntry lifecycle to the activity root, which caused the node-list popup 0×0 regression (#5684).
Fix
Re-introduce owner propagation, but scoped to
LocalView.current(the map screen's host view, an ancestor of the internally-createdMapView) instead ofview.rootView:ViewTreeLifecycleOwner+SavedStateRegistryOwneron the map host view so the renderer's internalComposeViewcan resolve them.Lifecycle.STARTEDguard to skip the cluster renderer's async-Handlerrender after the screen has stopped.Clustering(...),clusterItemContent, and the precision-circleclusterItemDecorationare unchanged — no feature regression.Caveats
spotlessCheck,detekt,:androidApp:compileGoogleDebugKotlinall pass) but not runtime-verified here (needs a Maps key + realgoogle-services.json). Suggest a smoke test: zoom to form/break clusters on the map, then navigate back and open a node-list popup to confirm popups still render.🤖 Generated with Claude Code