2010-11-11 67 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