fix(map): initialize Maps SDK before building marker bitmap descriptors#5709
Merged
Conversation
BitmapDescriptorFactory only works after the Maps SDK has been initialized, which normally happens when a GoogleMap/MapView is created. The Canvas marker descriptors added in #5702 are built during composition; on the node-detail inline map the marker icon is computed (InlineMap.kt) before that screen's GoogleMap has loaded the SDK, so BitmapDescriptorFactory.fromBitmap crashes with a fatal NullPointerException "IBitmapDescriptorFactory is not initialized". Call MapsInitializer.initialize(context) before creating any descriptor in rememberNodeChipDescriptor/rememberEmojiMarkerDescriptor. It is synchronous and idempotent, so it is a no-op once the SDK is already up (e.g. on the full map screen, where a GoogleMap is already present). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jamesarich
added a commit
that referenced
this pull request
Jun 2, 2026
…p, drop Google Maps leftovers Rebased onto main and dusted off the MapLibre Compose Multiplatform branch. - Bump maplibre-compose 0.12.1 -> 0.13.0 and migrate the redesigned location API (BearingUpdate.TRACK_LOCATION -> TRACK_AUTOMATIC; LocationPuck locationState -> location). - desktopApp: add a host-detecting maplibre-native-bindings-jni runtime backend so the desktop base map renders (Metal on macOS arm64, OpenGL on Linux/Windows amd64). Without it Gradle links no native renderer and the map canvas is black. - Gate Compose map overlays off on the JVM target via a mapOverlaysSupported expect/actual flag (true Android/iOS, false desktop). maplibre-compose 0.13.0 stubs the desktop layers/sources API with TODO(), so composing markers/waypoints/tracks/traceroute threw NotImplementedError and tore down the window. Desktop now renders base-map-only; overlays auto-enable when upstream implements desktop layers. - Remove orphaned Google Maps leftovers the rebase carried over from main's #5702/#5709 marker work (MarkerBitmapRenderer.kt + play-services-maps); this branch replaces Google Maps entirely. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jamesarich
added a commit
that referenced
this pull request
Jun 3, 2026
…ine-map crash structurally The late-May/early-June crash-fix flurry introduced app-side MapsInitializer calls from Compose to work around a "BitmapDescriptorFactory is not initialized" crash on the node-detail inline map (#5709), then extended it to the main map (#5715). maps-compose initializes the SDK itself when a GoogleMap creates its MapView, and the idiom is to build BitmapDescriptors inside a live map. Initializing from Compose (ahead of / racing the MapView's own init) correlates with the LATEST-renderer vector base map rendering black on affected devices ("Normal" black while satellite/terrain/hybrid render fine). Open-tag bisection of a field report (fine at open.16/17, black at open.20) places the inline-map regression at open.19 and the main-map regression at open.20. Revert to the pre-flurry, library-idiomatic initialization: - delete MapsSdkInitializer; remove all app-side MapsInitializer calls (the MapView init LaunchedEffect and MarkerBitmapRenderer's ensureMapsInitialized; buildNodeChipDescriptor drops its now-unused Context param) - fix the inline-map crash structurally: build the marker descriptor inside InlineMap's GoogleMap content, where the SDK is already initialized, exactly like the main map (which never crashed) - drop the redundant play-services-maps version pin; maps-compose pulls 20.0.0 transitively via maps-ktx Every descriptor build site now sits inside a live map, so no app-side init is needed and the crash cannot recur. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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
New FATAL on the node-detail screen (released alongside #5702/#5704/#5708):
BitmapDescriptorFactoryonly works after the Maps SDK has been initialized, which normally happens when aGoogleMap/MapViewis created. The Canvas marker descriptors introduced in #5702 are built during composition — and on the node-detail inline map the marker icon is computed (InlineMap.kt:52, outside/before theGoogleMap {}) before that screen'sGoogleMaphas loaded the SDK, soBitmapDescriptorFactory.fromBitmap()throws.This is why it only bites the inline map: on the full map screen a
GoogleMapis already present, so the factory is initialized by the time markers render.Fix
Call
MapsInitializer.initialize(context)before creating any descriptor, centralized inrememberNodeChipDescriptor/rememberEmojiMarkerDescriptor. It is synchronous and idempotent, so it's a no-op once the SDK is already up. Centralizing in the renderer covers every call site (inline map, waypoint markers, full map) and any future ones.Notes
MapsInitializer.initialize(Context)is deprecated in favor of the async renderer-callback overload, but we need the synchronous guarantee here; suppressed locally with a comment.spotlessCheck,detekt,:androidApp:compileGoogleDebugKotlinall pass). Not runtime-verified here (needs a Maps key + realgoogle-services.json) — suggest a smoke test: open a node's detail screen (Position section) directly after a cold start, before visiting the full map.🤖 Generated with Claude Code