Skip to content

Sensor listener leak causes IllegalStateException: exceeded the maximum limit 128 in LocationComponentCompassEngine #4045

@radityagumay

Description

@radityagumay

MapLibre Android Version

12.0.1

Android SDK Version

Android 10+ (issue seen on recent versions)

Device

Most devices

What happened?

Image

Repeated calls to addCompassListener/registerSensorListeners lead to sensor listener registrations without corresponding unregistrations, causing the app to eventually exceed Android's 128-sensor-listener limit. This results in a crash:

Fatal Exception: java.lang.IllegalStateException: register failed, the sensor listeners size has exceeded the maximum limit 128
at android. hardware.SystemSensorManager.registerListenerImpl(SystemSensorManager.java:226)
(...)
at org.maplibre.android.location.LocationComponentCompassEngine.registerSensorListeners(LocationComponentCompassEngine. java:275)
at org.maplibre.android.location.LocationComponentCompassEngine.addCompassListener(LocationComponentCompassEngine.java:83)
(...)

Expected: Sensors should not be re-registered beyond the maximum limit. Listeners should always be properly unregistered—especially during Compose recompositions or when the map is disposed.

Steps to reproduce

  1. Integrate MapLibre Android SDK in a Jetpack Compose-based project
  2. Frequently update camera/render state or rapidly recompose/detach views with a MapLibre map
  3. Observe application crash with IllegalStateException mentioned above, especially after extensive navigation/render mode switches

Renderer

No response

Relevant log output

Fatal Exception: java.lang.IllegalStateException: register failed, the sensor listeners size has exceeded the maximum limit 128
    at android.hardware.SystemSensorManager.registerListenerImpl(SystemSensorManager.java:226)
    at android.hardware. SensorManager.registerListener(SensorManager.java:833)
    at android.hardware.SensorManager.registerListener(SensorManager.java:740)
    at org.maplibre.android. location.LocationComponentCompassEngine. registerSensorListeners(LocationComponentCompassEngine.java:275)
    at org.maplibre.android.location.LocationComponentCompassEngine.addCompassListener(LocationComponentCompassEngine.java:83)
    at org.maplibre.android.location.LocationComponent.updateCompassListenerState(LocationComponent.java:1220)
    at org.maplibre.android.location.LocationComponent.setRenderMode(LocationComponent.java:456)
    at com.maplibre.compose. runtime.nodes.MapCameraNodeKt.cameraUpdate(MapCameraNode.kt:168)
    at com.maplibre.compose.runtime.nodes.MapCameraNodeKt$MapCameraNode$2$1.invoke(MapCameraNode.kt:73)
    at com.maplibre.compose.runtime.nodes.MapMutableStateNode.onAttached(MapComposeNode. kt:56)
    (...)

Additional context

Suggested fix:
Add defensive logic in registerSensorListeners() so it does not reregister listeners if already registered. Best practice also involves ensuring listeners are always unregistered (such as in onDispose in Compose integration, or component destruction of MapView/LocationComponent).

See [LocationComponentCompassEngine.java](https://github.com/maplibre/maplibre-native/blob/main/platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/location/LocationComponentCompassEngine. java) and lines around register/unregister logic for context.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions