Android MapView 内存使用率高的原因

发布于 2024-10-02 09:18:35 字数 4816 浏览 3 评论 0原文

我发现 GC 在我的地图活动中频繁释放内存,我无法找出原因,这种情况发生在地图开始构建标题时,即当我们滑动地图时。最终,由于内存越界异常,活动停止并强制退出。活动点存储在数组列表中的各个位置的地理点。随附的图像显示了这一点。

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 createItem(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();



     }
 }

我很高兴知道原因。当我滑动地图

 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

alt text时显示的日志

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 createItem(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

alt text

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情未る 2024-10-09 09:18:35

ItemizedOverlay 适用于适度数量的点。您的屏幕截图表明您可能有太多的点需要 ItemizedOverlay 的实现来支持。

我将首先禁用您的覆盖并查看您的 GC 问题是否消失。然后,引入少量点(例如 10 个)并观察事物的行为方式。如果一切正常,并且您通常会在地图上放置数百或数千个点,则您将需要编写自己的自定义 Overlay 类,该类更适合您的场景。

另一方面,如果您的 GC 问题存在且几乎没有点,那么可能是其他问题(例如,将地图放在选项卡中)。

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文