2010-11-11 66 views
0

我发现GC在我的地图活动中频繁释放内存,我无法找出原因,当地图开始构建标题时发生这种情况,即当我们滑动地图时。最终,由于内存超出限制的异常,活动停止强制退出。该活动指出存储在数组列表中的各个位置的地理点。图像封闭显示这一点。Android MapView中内存使用率高的原因

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

回答

0

ItemizedOverlay非常适用于点的中等数量的日志。您的屏幕截图表明您可能有太多的积分来支持ItemizedOverlay的实施。

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

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

+0

我试过没有标签的相同代码,只有5分,但我的自定义OverlayItem类获取不断调用,因为我滑动map.Placing自定义OverlayItem类getMarker方法上的日志语句证明了这一点。任何更好的方式来编写自定义的OverlayItem类? – ganesh 2010-11-12 10:31:57

+0

@ganesh:“但我的自定义OverlayItem类继续调用,因为我滑动地图” - 当然。 “你有没有更好的方法来编写自定义的OverlayItem类?” - 你似乎正在处理我的一个样本,显然需要优化。 :-(getMarker()'方法应该返回预先配置的'Drawables',而不是通过你(和我)每次的代码。我的道歉 - 我的实现适用于四标记地图,但没有比这更多的了,我会在即将到来的更新中修正它。 – CommonsWare 2010-11-12 12:06:57