Android MapView всегда вызывает OutOfMemoryError во вложенных элементах - PullRequest
8 голосов
/ 28 марта 2011

Я пытаюсь создать MapView (в настоящее время без наложений) внутри некоторых вложенных элементов. Это в основном что-то вроде 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"/>

Кажется, хорошо для меня. Больше ничего я не делаю с ним при запуске, но это всегда вызывает следующее:

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}

У вас есть идея, почему это так и что я могу сделать, чтобы избавиться от этого? Я не могу вынести это из этого представления, поскольку это место, где мне это нужно.

Спасибо!

Ответы [ 7 ]

11 голосов
/ 21 февраля 2012

Я обнаружил кое-что довольно простое.

Просто поместите MapView внутри FrameLayout. Пусть FramgeLayout будет wrap_content | wrap_content и все нормально :) 1003 *

Не удалось:

<?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>

Я получаю следующую трассировку стека:

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)

Вот решение:

<?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>

Привет, Marco

6 голосов
/ 19 апреля 2011

У меня тоже была эта проблема, она возникает, когда вы пытаетесь указать точные размеры карты. Установите одно из измерений в fill_parent или wrap_content, и пусть другое будет любым измерением, которое вы хотите. Это должно сработать.

2 голосов
/ 27 января 2012

steemcb корректно, но, к сожалению есть также ошибка в MapView, которая приводит к тому, что это происходит , даже если ваш макет хорош. Я получил точно такой же след стека, какваша.Это хрупкий компонент, и небольшие изменения в типе макета приведут к его неожиданному выходу из строя, особенно если он заключен в ScrollLayout.

. Еще никто не обращался к нему из проекта Android.

2 голосов
/ 26 мая 2011

Взгляните на следующий поток:

Проблема 2181: Утечка памяти в системе при использовании MapView

Похоже, это что-то внутреннее в MapActivity.Эта ветка существует уже более двух лет, и она не была зафиксирована как исправленная ...

Редактировать: пробовал описанное там решение, и оно привело меня к аналогичному решению:

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
    }
2 голосов
/ 04 апреля 2011

Я действительно не вижу, где вы получаете OutOfMemoryError? Я вижу это:

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

Что говорит о том, что вы можете создать MapView только внутри класса, который расширяет MapActivity, и это означает, что вы этого не делаете?

1 голос
/ 07 июля 2011

На самом деле это вызвано размещением MapView в Scrollview.См. android MapView всегда вызывает OutOfMemoryError во вложенных элементах для дополнительной информации.

0 голосов
/ 30 июня 2011

На самом деле это вызвано тем, что Scrollview создает буфер для представления в каждой возможной позиции полосы прокрутки, чтобы обеспечить быструю и плавную прокрутку.Поскольку MapView довольно большой, когда плитки загружаются во время фазы измерения, результирующий буфер, созданный ScrollView, может быть огромным (около 128 МБ).Если вы не установите в своем эмуляторе более 256 МБ оперативной памяти и кучи, он выйдет из строя с ошибкой нехватки памяти.Вы можете установить в своем эмуляторе 512 МБ оперативной памяти и пространства кучи, но ваше приложение будет зависать на любом устройстве с менее чем 512 МБ оперативной памяти или недостаточным пространством кучи.Лучше всего удалить MapView из ScrollView.

...