Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android MapView always causes an OutOfMemoryError in nested elements

I am trying to create a MapView (currently without any overlays) inside some nested elements. It is basically something like 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"/>

Seems fine for me. There is nothing more that I do with it on startup but it always causes the following:

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}

Do you have any idea why this is and what I can do to get rid of it? I can't take it out of that view as it is the place where I need it.

Thank you!

like image 792
ShadowMare Avatar asked Mar 28 '11 14:03

ShadowMare


4 Answers

I found out something quite simple.

Just place the MapView inside a FrameLayout. Let the FramgeLayout be wrap_content | wrap_content and everything is fine :)

This one fails:

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

I get the following stacktrace:

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)

An here the solution:

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

Greetings, Marco

like image 182
DaRolla Avatar answered Nov 26 '22 10:11

DaRolla


I had this problem as well, it occurs when you try to specify the exact dimensions of a mapview. Set one of the dimensions to fill_parent or wrap_content and let the other be whatever dimension you want. That should do the trick.

like image 38
steemcb Avatar answered Nov 26 '22 12:11

steemcb


I don't really see where you are getting an OutOfMemoryError? I do see this:

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

Which says you can only create a MapView inside a class that extends MapActivity, and it implies that you do not do this?

like image 43
Nanne Avatar answered Nov 26 '22 12:11

Nanne


Take a look at the following thread:

Issue 2181:Memory leak in system when using MapView

Seems like this is something internal in MapActivity. The thread is alive for over two years now and it was not reported as fixed...

Edit: tried the solution described there and it led me to a similar solution:

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
    }
like image 34
Muzikant Avatar answered Nov 26 '22 12:11

Muzikant