Repeating 6 bitmas taken from drawable on map causes out of memory error-Collection of common programming errors

I already tried to find a solution to my problem in this and in some other sites but with no luck. I have a map (Google map V2) set on my app. This map is full of markers (around 450) and each marker has an icon set from a drawable file. The drawable files are in total 6 so there are about 450 markers repeating 6 drawables (each different icon refers to a location on the map). When I first launch the map, there are no problems and everything works fine. But if I go back to the previous screen and launch again the map, the app crashes with an out of memory error. I think the problem is due to the fact that the system is keeping in memory all the bitmaps, with an incredible waste of resources, seen that the drawables are only six.

I tried to reference the bitmaps to the application context as suggested here with no good results. Is there an easy way to solve this issue?

Line 324:

if (IDTipologia.get(i).equals("1")) {
            setLoghino(R.drawable.chieseluoghidiculto);
            //iconcina = BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE);
            Bitmap icon = BitmapFactory.decodeResource(getApplicationContext().getResources(),
                    R.drawable.markerchiese);
            iconcina = BitmapDescriptorFactory.fromBitmap(icon);
}

ad so on until the 6th drawable.

Logcat:

E/AndroidRuntime(10990): FATAL EXCEPTION: main
E/AndroidRuntime(10990): java.lang.OutOfMemoryError
E/AndroidRuntime(10990):    at android.graphics.Bitmap.nativeCreateFromParcel(Native   Method)
E/AndroidRuntime(10990):    at android.graphics.Bitmap.access$000(Bitmap.java:28)
E/AndroidRuntime(10990):    at android.graphics.Bitmap$1.createFromParcel(Bitmap.java:1052)
E/AndroidRuntime(10990):    at android.graphics.Bitmap$1.createFromParcel(Bitmap.java:1044)
E/AndroidRuntime(10990):    at com.google.android.gms.maps.model.internal.IBitmapDescriptorFactoryDelegate$Stub.onTransact(IBitmapDescriptorFactoryDelegate.java:101)
E/AndroidRuntime(10990):    at android.os.Binder.transact(Binder.java:297)
E/AndroidRuntime(10990):    at com.google.android.gms.internal.h$a$a.a(Unknown Source)
E/AndroidRuntime(10990):    at com.google.android.gms.maps.model.BitmapDescriptorFactory.fromBitmap(Unknown Source)
E/AndroidRuntime(10990):    at it.eventitrapani.appaeventitp.ElencoMappaTutteCoseDaVedere.addMarkersToMap(ElencoMappaTutteCoseDaVedere.java:324)
E/AndroidRuntime(10990):    at it.eventitrapani.appaeventitp.ElencoMappaTutteCoseDaVedere.setUpMap(ElencoMappaTutteCoseDaVedere.java:269)
E/AndroidRuntime(10990):    at it.eventitrapani.appaeventitp.ElencoMappaTutteCoseDaVedere.setUpMapIfNeeded(ElencoMappaTutteCoseDaVedere.java:257)
E/AndroidRuntime(10990):    at it.eventitrapani.appaeventitp.ElencoMappaTutteCoseDaVedere.onCreate(ElencoMappaTutteCoseDaVedere.java:208)
E/AndroidRuntime(10990):    at android.app.Activity.performCreate(Activity.java:4470)
E/AndroidRuntime(10990):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1052)
E/AndroidRuntime(10990):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1931)
E/AndroidRuntime(10990):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1992)
E/AndroidRuntime(10990):    at android.app.ActivityThread.access$600(ActivityThread.java:127)
E/AndroidRuntime(10990):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1158)
E/AndroidRuntime(10990):    at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(10990):    at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(10990):    at android.app.ActivityThread.main(ActivityThread.java:4511)
E/AndroidRuntime(10990):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(10990):    at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(10990):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
E/AndroidRuntime(10990):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
E/AndroidRuntime(10990):    at dalvik.system.NativeStart.main(Native Method)
  1. First of all, why are you loading your bitmaps from resources like that? You can get a Drawable directly from your resources getResources().getDrawable(R.drawable.blah). If you retrieve the Drawable like that, they will all share the underlying Bitmap, so there would only be N (where N is the number of marker icons you have) bitmaps loaded in memory.

    Now, if you are applying some transformation to the drawable you might need to call mutate() on it first to get a new Drawable with a separate state (otherwise if you make one transparent ALL of them will become transparent).

    Update: Solution was to use the marker icon initialization that uses a resource ID instead of a bitmap directly:

    markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)));
    

Originally posted 2013-11-27 05:07:49.