fix: pin ViewTreeLifecycleOwner/SavedStateRegistryOwner on MapView to prevent info window crash - #972
Open
kikoso wants to merge 2 commits into
Open
fix: pin ViewTreeLifecycleOwner/SavedStateRegistryOwner on MapView to prevent info window crash#972kikoso wants to merge 2 commits into
kikoso wants to merge 2 commits into
Conversation
… prevent info window crash On compose-ui 1.11+, MarkerInfoWindow/MarkerInfoWindowContent can crash with "Composed into the View which doesn't propagate ViewTreeLifecycleOwner!" when the Maps SDK measures the info window's ComposeView from its own Handler after Compose has already unparented the MapView (e.g. LazyColumn recycling/detach). The ViewTreeLifecycleOwner/ViewTreeSavedStateRegistryOwner tags live on the AndroidView holder that is the MapView's parent, so once that parent link is severed the info window's ComposeView can no longer resolve an owner and AbstractComposeView.onMeasure throws (fatal starting with compose-ui 1.11, where owner resolution moved into onMeasure). Pin both owners directly onto the MapView itself so they stay resolvable from its own subtree regardless of where Compose has parented it. Fixes #971
The pin added in the previous commit stops the Maps SDK's async info-window render from throwing "Composed into the View which doesn't propagate ViewTreeLifecycleOwner!" once Compose has unparented the MapView. But on this codebase's bitmap-based info window rendering (#953), that same detached-render path now hits a different crash: renderComposableToBitmap's own check() rejects the zero-size measurement that naturally results from compositing a ComposeView that never got a real window attachment. A MapView that's mid-teardown has nothing worth rendering anyway, so treat that specific case (zero-size AND not attached to window) as "nothing to show" instead of a hard failure: renderComposableToBitmap now returns null, and ComposeInfoWindowAdapter propagates that through to the Maps SDK's already-nullable getInfoContents()/getInfoWindow(). Zero-size content on an attached MapView still throws with the original message, since that is a genuine content-authoring bug rather than a teardown race. Verified on a physical device (Pixel 4, Android 13, GMS 26.32.62, phoenix renderer) using the exact LazyColumn-recycling repro from #971: crashes within the first ~20 cycles without both fixes, survives 420+ cycles (60s, process alive throughout) with both applied.
Contributor
Code Coverage
|
kikoso
marked this pull request as ready for review
August 20, 2026 15:08
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.
Summary
Fixes #971.
On compose-ui 1.11+,
MarkerInfoWindow/MarkerInfoWindowContentcan crash with:The Maps SDK measures the info-window
ComposeViewfrom its ownHandler, asynchronously. If that measure lands after Compose has unparented theMapView(e.g.LazyColumnrecycling/detach), theComposeViewcan no longer resolve aViewTreeLifecycleOwner/ViewTreeSavedStateRegistryOwnerby walking up its ancestors, because those tags live on theAndroidViewholder — theMapView's parent — not on theMapViewitself.AbstractComposeView.onMeasurethen throws (this became fatal in compose-ui 1.11, which moved owner resolution intoonMeasure; on 1.10 it silently rendered blank instead).Fix
Two commits:
Pin the ViewTree owners onto the
MapView(GoogleMap.kt) — at creation in theAndroidViewfactory, and on everyupdatein case the owner identity changes. This keeps the owner lookup resolvable from within the map's own subtree regardless of where Compose has parented theMapView, without changing behavior while attached (same owner instancesAndroidViewalready assigns to the parent).Handle the now-reachable zero-size render gracefully (
MapComposeViewRender.kt,ComposeInfoWindowAdapter.kt) — with (1) alone, the original crash is gone, but on this codebase's bitmap-based info-window rendering (fix: avoid re-parenting crash for MarkerInfoWindowContent/MarkerInfoWindowComposable #953) the same detached-render race surfaces a second crash:renderComposableToBitmap's owncheck()rejects the zero-size measurement that naturally results from compositing aComposeViewthat never got a real window attachment. AMapViewmid-teardown has nothing worth rendering anyway, so that specific case (zero-size and not attached to window) now returnsnullinstead of throwing, propagated through the already-nullablegetInfoContents()/getInfoWindow(). Zero-size content on an attachedMapViewstill throws with the original message — that's a genuine content-authoring bug, not a teardown race.Test plan
./gradlew :maps-compose:compileDebugKotlin— builds clean./gradlew :maps-compose:lintDebug— no new issuesLazyColumn-recycling repro from Maps Compose: MarkerInfoWindow crashes with "Composed into the View which doesn't propagate ViewTreeLifecycleOwner!" on compose-ui 1.11+ when the map is detached #971 (showInfoWindow()+ scroll-out in the same beat, repeated in a loop):ViewTreeLifecycleOwnerIllegalStateException, stack trace matching Maps Compose: MarkerInfoWindow crashes with "Composed into the View which doesn't propagate ViewTreeLifecycleOwner!" on compose-ui 1.11+ when the map is detached #971 line-for-line, within the first ~20 cycles.renderComposableToBitmap's zero-sizecheck()) — this codebase's info-window rendering had already been rewritten to a bitmap-based approach (fix: avoid re-parenting crash for MarkerInfoWindowContent/MarkerInfoWindowComposable #953) since 8.4.0, exposing this second issue.🤖 Generated with Claude Code