Androide MapView siempre provoca un OutOfMemoryError en elementos anidados

Estoy tratando de crear un MapView (actualmente sin ninguna superposición) dentro de algunos elementos anidados. Es básicamente algo como ScrollView -> RelativeLayout -> RelativeLayout -> MapView

  <com.google.android.maps.MapView android:id="@+id/mapview" android:layout_width="420px" android:layout_height="300px" android:clickable="false" android:apiKey="key"/> 

Parece bien para mí. No hay nada más que hago con él en el arranque, pero siempre causa lo siguiente:

 04-04 13:38:33.910: WARN/dalvikvm(13628): threadid=1: thread exiting with uncaught exception (group=0x40015560) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): FATAL EXCEPTION: main 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): java.lang.OutOfMemoryError 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android_maps_conflict_avoidance.com.google.googlenav.map.Map.resize(Map.java:1368) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android_maps_conflict_avoidance.com.google.googlenav.map.Map.resize(Map.java:1337) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at com.google.android.maps.MapView.onMeasure(MapView.java:590) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.view.View.measure(View.java:8313) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:581) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:365) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.view.View.measure(View.java:8313) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:581) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:365) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.view.View.measure(View.java:8313) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.widget.ScrollView.measureChildWithMargins(ScrollView.java:1072) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.widget.FrameLayout.onMeasure(FrameLayout.java:250) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.widget.ScrollView.onMeasure(ScrollView.java:296) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.view.View.measure(View.java:8313) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.widget.FrameLayout.onMeasure(FrameLayout.java:250) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.view.View.measure(View.java:8313) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.widget.LinearLayout.measureVertical(LinearLayout.java:531) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.widget.LinearLayout.onMeasure(LinearLayout.java:309) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.view.View.measure(View.java:8313) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.widget.FrameLayout.onMeasure(FrameLayout.java:250) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.view.View.measure(View.java:8313) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.view.ViewRoot.performTraversals(ViewRoot.java:839) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.view.ViewRoot.handleMessage(ViewRoot.java:1859) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.os.Handler.dispatchMessage(Handler.java:99) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.os.Looper.loop(Looper.java:123) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at android.app.ActivityThread.main(ActivityThread.java:3647) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at java.lang.reflect.Method.invokeNative(Native Method) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at java.lang.reflect.Method.invoke(Method.java:507) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 04-04 13:38:33.996: ERROR/AndroidRuntime(13628): at dalvik.system.NativeStart.main(Native Method) 04-04 13:38:34.027: WARN/ActivityManager(6000): Force finishing activity package/.home 04-04 13:38:34.527: WARN/ActivityManager(6000): Activity pause timeout for HistoryRecord{405336d0 package/.home} 

¿Tiene alguna idea de por qué esto es y lo que puedo hacer para deshacerse de él? No puedo sacarla de esa vista, ya que es el lugar donde la necesito.

¡Gracias!

Me enteré de algo muy simple.

Simplemente coloque el MapView dentro de un FrameLayout. Deje que el FramgeLayout sea wrap_content | Wrap_content y todo está bien 🙂

Este falla:

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ScrollView android:layout_width="fill_parent" android:layout_height="fill_parent"> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <view android:layout_width="100dip" android:layout_height="90dip" class="com.google.android.maps.MapView" android:apiKey="@string/API_KEY" android:clickable="true" /> </RelativeLayout> </ScrollView> </RelativeLayout> 

Obtengo el stacktrace siguiente:

 java.lang.OutOfMemoryError at com.google.googlenav.map.Map.resize(Unknown Source) at com.google.android.maps.MapView.onMeasure(MapView.java:554) at android.view.View.measure(View.java:8172) at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:578) at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:362) at android.view.View.measure(View.java:8172) at android.widget.ScrollView.measureChildWithMargins(ScrollView.java:989) at android.widget.FrameLayout.onMeasure(FrameLayout.java:245) at android.widget.ScrollView.onMeasure(ScrollView.java:286) at android.view.View.measure(View.java:8172) at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:578) at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:362) at android.view.View.measure(View.java:8172) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3140) at android.widget.FrameLayout.onMeasure(FrameLayout.java:245) at android.view.View.measure(View.java:8172) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3140) at android.widget.FrameLayout.onMeasure(FrameLayout.java:245) at android.view.View.measure(View.java:8172) at android.view.ViewRoot.performTraversals(ViewRoot.java:805) at android.view.ViewRoot.handleMessage(ViewRoot.java:1744) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:144) at android.app.ActivityThread.main(ActivityThread.java:4937) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:521) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) at dalvik.system.NativeStart.main(Native Method) 

Aquí la solución:

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ScrollView android:layout_width="fill_parent" android:layout_height="fill_parent"> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content"> <view android:layout_width="100dip" android:layout_height="90dip" class="com.google.android.maps.MapView" android:apiKey="@string/API_KEY" android:clickable="true" /> </FrameLayout> </RelativeLayout> </ScrollView> </RelativeLayout> 

Saludos, Marco

También tuve este problema, se produce cuando se intenta especificar las dimensiones exactas de un mapa. Establezca una de las dimensiones a fill_parent o wrap_content y deje que el otro sea cualquier dimensión que desee. Eso debería hacer el truco.

Realmente no veo dónde obtiene un OutOfMemoryError? Veo esto:

 Caused by: java.lang.IllegalArgumentException: MapViews can only be created inside instances of MapActivity. 

¿Qué dice que sólo puede crear un MapView dentro de una clase que extienda MapActivity, e implica que no lo haga?

Echa un vistazo al siguiente hilo:

Problema 2181: Fuga de memoria en el sistema cuando se utiliza MapView

Parece que esto es algo interno en MapActivity. El hilo está vivo durante más de dos años y no se informó como fijo …

Edit: probé la solución descrita allí y me llevó a una solución similar:

 try { Field mConfigField = MapActivity.class.getDeclaredField("mConfig"); mConfigField.setAccessible(true); Object mConfig = mConfigField.get(this); if (null != mConfig) { Field mConfigContextField = mConfig.getClass().getDeclaredField("context"); mConfigContextField.setAccessible(true); mConfigContextField.set(mConfig, null); mConfigField.set(this, null); } } catch (Exception ex) { // Do error handling } 

Steemcb es correcto, pero desafortunadamente también hay un error en MapView que hace que esto suceda incluso si su diseño es bueno. Tengo el mismo rastro de pila como el tuyo. Es un componente frágil y pequeños cambios en el tipo de diseño harán que se rompa inesperadamente, especialmente si está envuelto en un ScrollLayout .

Aún no ha sido abordado por nadie del proyecto de Android.

En realidad, es causado por la colocación de la MapView en un Scrollview. Ver android MapView siempre provoca un OutOfMemoryError en elementos anidados para obtener más información.

En realidad, es causado por Scrollview la creación de un búfer para contener la vista en cada posición posible de la barra de desplazamiento para permitir el desplazamiento rápido y suave. Puesto que un MapView es bastante grande cuando los azulejos se cargan durante la fase de la medida entonces el almacenador intermediario resultante creado por ScrollView puede ser enorme (alrededor de 128 M). A menos que configure su emulador para que tenga más de 256 M de espacio de memoria RAM y montón, fallará con un error de memoria. Usted podría configurar su emulador para tener 512M de RAM y espacio de montón, pero su aplicación se bloquea en cualquier dispositivo que tiene menos de 512M de RAM o espacio de montón insuficiente. Lo mejor es quitar el MapView de ScrollView.

  • Android: Convertir secuencia a cadena sin quedarse sin memoria
  • Excepción OutOfMemory aparece mientras se desplaza la lista de imágenes
  • Fuga de memoria de Android: InputMethodManager, mapa de bits
  • ¿Cómo evitar OutOfMemory para TextView que contiene ilimitado ImageSpans?
  • ¿Excepción java.lang.outofmemoryerror?
  • Implementación de BackStack para Fragmentos en las pestañas de Android
  • Sugerencias para evitar errores de mapa de bits de memoria
  • Cómo solucionar OutOfMemoryError con LayerDrawable
  • Androide viewpager fuera de la memoria
  • Java.lang.OutOfMemoryError: android.support.v4.app.BackStackState de longitud 1279544898 se desbordaría
  • Android: Demasiada memoria asignada mientras usa png en lugar de imágenes vectoriales
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.