Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Fabric: ReactViewGroup cannot be cast to MapMarker in MarkerManager.onLayoutChange (leaked layout listener on recycled views)

Abierto Apto para principiantes
#5,987 1 comentario 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
84/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
android, java, react-native
Área
mobile

Línea de trabajo

Comienza en android/src/main/java/com/rnmaps/fabric/MarkerManager.java, en addView y su callback onLayoutChange, y luego reproduce el escenario de reciclaje de marcadores de Fabric reportado con contenido de marcador personalizado. Se considera terminado cuando los elementos secundarios reciclados ya no provocan un fallo cuando su elemento principal no es un MapMarker y el callback ya no afecta a los marcadores desconectados; verifícalo con la reproducción de Android proporcionada.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Summary

On the New Architecture (Fabric), MarkerManager.addView attaches an OnLayoutChangeListener to a marker's first child and never removes it. Because Fabric recycles views through a shared pool, that listener stays attached to the view after it has been reparented elsewhere, and the unchecked cast in the callback crashes the app:

com.facebook.react.views.view.ReactViewGroup cannot be cast to com.rnmaps.maps.MapMarker
        at com.rnmaps.maps.MarkerManager.onLayoutChange(MarkerManager.java:292)
        at android.view.View.layout(View.java:27317)
        at android.view.ViewGroup.layout(ViewGroup.java:6513)
        at com.facebook.react.fabric.mounting.SurfaceMountingManager.updateLayout(SurfaceMountingManager.kt:856)
        at com.facebook.react.fabric.mounting.mountitems.IntBufferBatchMountItem.execute(IntBufferBatchMountItem.kt:139)
        at com.facebook.react.fabric.mounting.MountItemDispatcher.dispatchMountItems(MountItemDispatcher.kt:250)
        at com.facebook.react.fabric.FabricUIManager.doFrameGuarded(FabricUIManager.java:1622)
Cause

android/src/main/java/com/rnmaps/fabric/MarkerManager.java:

if (index == 0) {
    child.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
        @Override
        public void onLayoutChange(View v, int left, int top, int right, int bottom, ...) {
            int newWidth = right - left;
            int newHeight = bottom - top;
            MapMarker marker = (MapMarker) v.getParent();   // <-- unchecked
            if (marker != null) {
                marker.update(newWidth, newHeight);
            }
        }
    });
}

The existing marker != null check does not help: the problem is not a null parent, it is a parent of the wrong type. The listener is registered once per addView and is never paired with a removeOnLayoutChangeListener, so it outlives the marker that installed it.

Reproduction

Using custom marker content (a <View> child rather than pinColor) for a set of markers that mount and unmount as data arrives, on a screen that also renders a reasonable number of ordinary <View>s:

<MapView>
  {riders.map(r => (
    <Marker key={r.uid} coordinate={{ latitude: r.lat, longitude: r.lng }}>
      <View style={styles.wrap}>
        <View style={styles.arrow} />
        <View style={styles.pill}><Text>{r.name}</Text></View>
      </View>
    </Marker>
  ))}
</MapView>

It is a race, so it does not reproduce on every launch. It became reliably reproducible in our app once the surrounding screen grew enough plain Views for the pool to hand a recycled marker child back out.

Environment
  • react-native-maps 1.29.0
  • react-native 0.87.1, New Architecture / Fabric enabled
  • Android, PROVIDER_GOOGLE
Suggested fix

Guard the cast:

-                        MapMarker marker = (MapMarker) v.getParent();
-                        if(marker != null){
-                            marker.update(newWidth, newHeight);
+                        if (v.getParent() instanceof MapMarker) {
+                            ((MapMarker) v.getParent()).update(newWidth, newHeight);
                         }

This has been running via patch-package in our app and resolves the crash with no behavioural change.

A more complete fix would also remove the listener when the child is detached (removeViewAt / onDropViewInstance), so recycled views do not keep firing callbacks into markers that no longer exist. I am happy to open a PR for either shape if you have a preference.

Lenguaje dominante
TypeScript
Estrellas
16k
Forks
5k
Merge medio
17 h 45 min
PR fusionados (30 d)
2

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de react-native-maps/react-native-maps

Todos los issues de react-native-maps/react-native-maps

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.