3

I have an app in which I read some gps data and I display them on the map and I also add an overlay at that position which is a small .png image.

I'm reading the data in an Async Task thread and in onProgressUpdate method I update my GUI by adding the overlay at a new position. Here is my code:

     Drawable marker;          
public void onCreate(Bundle savedInstanceState) {
            marker=getResources().getDrawable(R.drawable.curent_loc);
    marker.setBounds(0, 0, marker.getIntrinsicWidth(),
            marker.getIntrinsicHeight());

    }

In here I read the GPS data:

public class InitTask extends AsyncTask<Void, GeoPoint, Void> {
protected Void doInBackground(Void... voids) {

        p = new GeoPoint(latitude, longitude);
                    publishProgress(p);
                    Thread.sleep(1500);
                }

/*in here I update my GUI*/
  protected void onProgressUpdate(GeoPoint... progress1) {
    mapView.getOverlays().add(new SitesOverlay(marker,progress1[0]));
                theRouteDraw(progress1[0]);
                }
        }

So I read a new location and I add an overlay at that position. For that I use my class SitesOverlay that extends Overlay.

Everything goes well until at some point where I receive the following exception:

java.lang.OutOfMemoryError: bitmap size exceeds VM budget
 at android.graphics.BitmapFactory.nativeDecodeByteArray(Native Method)
at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:392)
at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:405)
at com.google.android.maps.StreetViewRenderer.getOverlay(StreetViewRenderer.java:149)
com.google.android.maps.StreetViewRenderer.renderTile(StreetViewRendere
at    com.google.android.maps.AndroidTileOverlayRenderer.renderTile(AndroidTileOverlayRenderer.java:62)
at com.google.googlenav.map.Map.drawTile(Unknown Source)
at com.google.googlenav.map.Map.drawMapBackground(Unknown Source)
at com.google.googlenav.map.Map.drawMap(Unknown Source)
at com.google.android.maps.MapView.drawMap(MapView.java:1029)
at com.google.android.maps.MapView.onDraw(MapView.java:468)
at android.view.View.draw(View.java:6535)
at android.view.ViewGroup.drawChild(ViewGroup.java:1531)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
at android.view.ViewGroup.drawChild(ViewGroup.java:1529)

I tried to recycle my drawable but still I get that error, and after a while I found this:

//decodes image and scales it to reduce memory consumption
private Bitmap decodeFile(File f){
    try {
        //Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f),null,o);

        //The new size we want to scale to
        final int REQUIRED_SIZE=70;

        //Find the correct scale value. It should be the power of 2.
        int width_tmp=o.outWidth, height_tmp=o.outHeight;
        int scale=1;
        while(true){
            if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
                break;
            width_tmp/=2;
            height_tmp/=2;
            scale*=2;
        }

        //Decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize=scale;
        return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
    } catch (FileNotFoundException e) {}
    return null;
}

I found that in here: Strange out of memory issue while loading an image to a Bitmap object

But I have a few problems in understanding it:

*First why is using a File f as a parameter? Is this the drawable I wanna use? Must this be done each time I use that drawable or only in onCreate()?

So if someone could explain how to use that I would be more than grateful, or if you have a simpler working solution it would be even better.

Community
  • 1
  • 1
adrian
  • 4,574
  • 17
  • 68
  • 119

1 Answers1

2

This has been a huge problem with Android for ages. The Bitmap class, getDrawable function etc relies on the underlying bitmap.h which is available as part of the NDK. Whenever a getDrawable returns a bitmap, due to some reason Android does not properly free the memory when we no longer need it.

One workaround I've used it to create a single static instance of the bitmap somewhere and weak reference it whenever you need to. This way atleast one instance of the bitmap is loaded onto the memory.

Hope this helps.

Mahadevan Sreenivasan
  • 1,144
  • 1
  • 9
  • 26
  • 1
    Could u show me a little bit of your code to see how u did that?Because I'm new to programming and this is not very easy for me to do.Thanks:) – adrian Jun 19 '11 at 14:34
  • You might want to check this out - http://stackoverflow.com/questions/4197794/android-custom-view-bitmap-memory-leak :) – Mahadevan Sreenivasan Jun 19 '11 at 14:47