2016-02-13 48 views
0

在我的Android應用程序中,我每10秒調用一次服務器請求,並使用標記更新地圖上的結果(創建位圖,我的標記具有圖像&文本)。我使用Android map utils library來創建我的佈局的位圖,這工作正常,但我的力量在一段時間後內存不足問題關閉。Android地圖內存異常

Note: 
My marker has image and text like a layout. 
its updates with dynamic result by every 10 seconds. 

我用了兩個主要的類從library

1. BubbleDrawable 2. IconGenerator,我已經使用這個兩個類來創建我的佈局的位圖。

在我的地圖活動中,我每10秒鐘調用一次庫並使用自定義標記刷新地圖。

代碼:

public class MainActivity extends Activity{ 

private IconGenerator icGen ; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     icGen = new IconGenerator(this); 
     serverResponse(); // this method call every 10 seconds 
    } // onCreate ends here. 

    void updateResult(String placeName){ 
     markerPin = googleMap.addMarker(new MarkerOptions().icon(BitmapDescriptorFactory.fromBitmap(icGen.makeIcon(placeName))) // dynamic name 
      .position(markerLatLng).anchor(0.5f, 1.0f)); // I got out of memory exception here 
     .... 
     googleMap.addMarker(markerPin);  
    } 

    void serverResponse(){ 
     JSONArray arr = new JSONArray(serverResponse); 
     for(int i=0;i<all.length();i++){ 
      name = arr.getJSONObject.getStrig(name); 
      updateResult(name); 
     } 
    } 
} 

我也沒辦法解決這個問題,請幫幫我。

+0

當您不再需要標記時,您是否刪除標記,或者在不刪除舊標記的情況下繼續添加新標記? – antonio

+0

我會檢查舊數據和新數據每次從服務器獲取新數據,如果發現任何地方的修改,然後我將刪除舊的標記並創建新的位圖並用作標記,未改變的地方的標記將不會被刪除。 –

+1

然後我會說你的'OutOfMemory'是由於在你的地圖上保留了大量的標記引起的。你真的不需要保留地圖中的所有標記(它會破壞性能),你只需要顯示可見的標記。所以你可以,例如刪除所有的標記('map.clear()')並在onCameraChange事件中添加可見的標記。爲此,您需要維護一個結構來存儲您從服務中下載的位置,並檢查這些位置是否在可見視口中。 – antonio

回答

2

從評論:

我要說的是你的內存不足是通過保持你的地圖 標記一個大數字引起的。你真的不需要在你的地圖中保留所有的標記 (它會破壞性能),你只需要顯示 可見的。因此,您可以刪除所有標記 (map.clear()),並在onCameraChange事件中添加可見標記。至 這樣做,您需要維護一個結構來存儲您從服務中下載的位置 ,並檢查這些位置是否在 可見視口中。

這裏,每次清除地圖相機更改和添加所有可見標記的例子(我只顯示相關的代碼,請考慮到這是沒有測試):

public class MainActivity extends Activity implements GoogleMap.OnCameraChangeListener, GoogleMap.OnMapReadyCallback { 
    private GoogleMap googleMap; 
    private List<Place> places = new ArrayList<>(); 

    // ... 

    void serverResponse() { 
     JSONArray arr = new JSONArray(serverResponse); 
     for (int i = 0; i < all.length(); i++) { 
      name = arr.getJSONObject.getStrig(name); 

      // TODO: Get the LatLong 

      // Add a new Place to the list 
      places.add(new Place(name, latLng)); 
     } 
    } 

    @Override 
    public void onCameraChange(final CameraPosition cameraPosition) { 
     // Clear the map to avoid keeping tons of markers 
     googleMap.clear(); 

     // Find the current visible region 
     final LatLngBounds bounds = googleMap.getProjection() 
       .getVisibleRegion().latLngBounds; 

     // Draw the visible markers 
     for (Place place : places) { 
      if (bounds.contains(place.getLatLng())) { 
       googleMap.addMarker(new MarkerOptions().icon(BitmapDescriptorFactory.fromBitmap(icGen.makeIcon(place.getName()))) 
         .position(place.getLatLng()).anchor(0.5f, 1.0f)); 
      } 
     } 
    } 

    @Override 
    public void onMapReady(GoogleMap googleMap) { 
     this.googleMap = googleMap; 
     googleMap.setOnCameraChangeListener(this); 
    } 

    private class Place { 
     private String name; 
     private LatLng latLng; 

     public Place(String name, LatLng latLng) { 
      this.name = name; 
      this.latLng = latLng; 
     } 

     public String getName() { 
      return name; 
     } 

     public void setName(final String name) { 
      this.name = name; 
     } 

     public LatLng getLatLng() { 
      return latLng; 
     } 

     public void setLatLng(final LatLng latLng) { 
      this.latLng = latLng; 
     } 
    } 
} 

也許您需要改進代碼,將List<Place>更改爲Map<String, Place>以確保您不會添加給定地點兩次。

+0

我已經使用上述邏輯,但onCameraChange方法將在放大或縮小時調用。我怎樣才能防止這個? –

+1

'onCameraChange'收到'CameraPosition',你可以從那裏得到'target'。您將需要比較當前的「目標」和舊的(您將需要保存它),並在縮放/平移時採取不同的行動 – antonio