开发者

Reason for High Memory usage in Android MapView

I found the GC kicks in frequently freeing memory in my map activity, I couldn't trace out the reason and this happens when map start constructing titles i.e when we slide the map. And eventually the activity stops to force quit due to memory out of bound exception. The activity points the geo points of various location stored in the arraylist. The image enclose show this.

public class DetailMapTab extends MapActivity{
private MapView map=null;
private MyLocationOverlay me=null;
private SitesOverlay sites=null;
String placename;
int position;
String lat;
String lon;
ArrayList<HashMap<String, String>> mylist =new ArrayList<HashMap<String, String>>();


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mapdetail);


//position -> is the selected record of the list 
//mylist -> contains record sets to display like name , lat and lon of various location
placename=mylist.get(position).get("Name");
lat=mylist.get(position).get("Latitude");
lon=mylist.get(position).get("Longitude");





map=(MapView)findViewById(R.id.map);

map.getController().setCenter(getPoint(Double.valueOf(lat),Double.valueOf(lon)));

map.getController().setZoom(17);
map.setBuiltInZoomControls(true);

sites=new SitesOverlay();
map.getOverlays().add(sites);

me=new MyLocationOverlay(this, map);
map.getOverlays().add(me);




}//oncreate

@Override
public void onResume() {
    super.onResume();

    me.enableCompass();
}       

@Override
public void onPause() {
    super.onPause();

    me.disableCompass();
}       

@Override
protected boolean isRouteDisplayed() {
    return(false);
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_S) {
        map.setSatellite(!map.isSatellite());
        return(true);
    }
    else if (keyCode == KeyEvent.KEYCODE_Z) {
        map.displayZoomControls(true);
        return(true);
    }
    else if (keyCode == KeyEvent.KEYCODE_H) {

        return(true);
    }

    return(super.onKeyDown(keyCode, event));
}

private GeoPoint getPoint(double lat, double lon) {
    return(new GeoPoint((int)(lat*1000000.0),(int)(lon*1000000.0)));
}

private class SitesOverlay extends ItemizedOverlay<CustomItem> {

    private List<CustomItem> items=new ArrayList<CustomItem>();


    public SitesOverlay() {
        super(null);

        //show selected record geo-point with a new map pin1

        items.add(new CustomItem(getPoint(Double.valueOf(lat),Double.valueOf(lon))," ", placename,getMarker(R.drawable.pin1)));



          //show the geo-points names with pin2

            for(int i=0;i<mylist.size();i++)
            {


                if(position!=i)
                {

                items.add(new CustomItem(getPoint(Double.valueOf(mylist.get(i).get("Latitude")),Double.valueOf(mylist.get(i).get("Longitude"))),"",mylist.get(i).get("Name"),getMarker(R.drawable.pin2)));
                }
            }
        }

    }
    populate();
    }

    @Override
    protected  CustomItem cre开发者_运维问答ateItem(int i) {
        return(items.get(i));
    }

    @Override
    public void draw(Canvas canvas, MapView mapView,boolean shadow) {
        super.draw(canvas, mapView, shadow);

    }

    @Override
    protected boolean onTap(int i) {
        //OverlayItem item=getItem(i);
        Toast.makeText(getApplicationContext(),items.get(i).getSnippet(),Toast.LENGTH_SHORT).show();
        return(true);
    }

    @Override
    public int size() {
        return(items.size());
    }



    private Drawable getMarker(int resource) {
        Drawable marker=getResources().getDrawable(resource);

        marker.setBounds(0, 0, marker.getIntrinsicWidth(),marker.getIntrinsicHeight());
        boundCenterBottom(marker);  

        return(marker);
    }
}



 class CustomItem extends OverlayItem {
    Drawable marker=null;


    CustomItem(GeoPoint pt, String name, String snippet, Drawable marker) {
        super(pt, name, snippet);

        this.marker=marker;

    }

    @Override
    public Drawable getMarker(int stateBitset) {
        Drawable result= marker;

        setState(result, stateBitset);

        return(result);
    }


}


  public void onDestroy(){
         super.onDestroy();


        map=null;
        me=null;
        sites=null;

        gr=null;
        placename=null;
        lat=null;
        lon=null;
        mylist =null;
         System.gc();



     }
 }

I am glad to know the reason. The log shown as when I slide the map

 11-11 15:39:55.072: DEBUG/dalvikvm(222): GC freed 439 objects / 83360 bytes in 106ms
 11-11 15:39:56.052: DEBUG/dalvikvm(107): GC freed 3568 objects / 197464 bytes in 138ms
 11-11 15:39:57.451: DEBUG/dalvikvm(222): GC freed 135 objects / 41456 bytes in 101ms
 11-11 15:39:59.891: DEBUG/dalvikvm(222): GC freed 94 objects / 42112 bytes in 134ms
 11-11 15:44:27.481: DEBUG/dalvikvm(104): GC freed 7472 objects / 406240 bytes in 140ms

Reason for High Memory usage in Android MapView


ItemizedOverlay works well for modest numbers of points. Your screenshot suggests that you may have too many points for ItemizedOverlay's implementation to support.

I would start by disabling your overlay and seeing if your GC problems go away. Then, introduce a small number of points (e.g., 10) and see how things behave. If everything is OK, and you ordinarily would be putting hundreds or thousands of points on the map, you will need to write your own custom Overlay class that is more optimized for your scenario.

If, on the other hand, your GC problems exist with few to no points, then perhaps something else is the problem (e.g., having the map in a tab).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜