2013-08-31 75 views
8

我從一個URL使用Picasso library添加從URL標記與畢加索

作爲標記不是一個ImageView的我試圖用一個目標,而不是

for(int x =0; x < mapIcon_url.length; x++){ 

    Picasso.with(getActivity()).load(mapIcon_url[x]).resize(marker_size, marker_size+15).into(new Target() { 

     @Override 
     public void onSuccess(Bitmap b) { 
      bitmapMarker = BitmapDescriptorFactory.fromBitmap(b); 


      //create marker option 
      if(b != null) 
       markerOptions = new MarkerOptions().position(marker_position).icon(bitmapMarker)); 
      else 
       markerOptions = new MarkerOptions().position(marker_position).icon(BitmapDescriptorFactory.fromResource(R.drawable.placeholder_pin)).snippet(String.valueOf(x)); 

      marker = map.addMarker(markerOptions);        
     } 

     @Override 
     public void onError() { 

      //create marker option         
      markerOptions = new MarkerOptions().position(marker_position).icon(BitmapDescriptorFactory.fromResource(R.drawable.placeholder_pin)).snippet(String.valueOf(x)); 
      marker = map.addMarker(markerOptions); 

     } 
    }); 
} 

我添加標記到我的地圖在循環中添加大約20個標記,但我發現在第一次運行代碼時只添加了5或7個標記,因此我已經切換到使用lib和這樣的AsyncTask。

for(int x =0; x < mapIcon_url.length; x++){ 

    new AddMarker().execute(mapIcon_url[x]); 
} 


public class AddMarker extends AsyncTask<String, Integer, BitmapDescriptor> { 

    BitmapDescriptor bitmapMarker1; 
    VenueDetails myVenue; 

    @Override 
    protected BitmapDescriptor doInBackground(String... url) { 
     myUrl = url[0]; 
     try { 
      bitmapMarker1 = BitmapDescriptorFactory.fromBitmap(Picasso.with(getActivity()).load(myUrl).resize(marker_size, marker_size+15).get()); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     return bitmapMarker1; 
    } 

    protected void onPostExecute(BitmapDescriptor icon) { 

     try { 

      map.addMarker(new MarkerOptions().position(marker_position).icon(icon))); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

不過我有點擔心這種方法能否給我一些問題,當我有很多標記的說一下100.我的問題是,這是做到這一點的最好辦法,如果沒有什麼其他選擇能我試試。

+0

我會專注於調試你的第一種方法。使用斷點或記錄語句來確定您無法獲取標記的位置。 – CommonsWare

+0

我在調用Picasso類之前,也在目標的onSucess和onError重寫方法中使用了日誌語句。日誌顯示外觀被稱爲20次,onSucess被稱爲幾次,onError從未被調用過。 –

+0

傑克昨天剛剛發佈了Picasso 2.0.0--如果您還沒有這樣做,您可以嘗試一下。否則,您可能會嘗試創建一個可重複的測試用例,並向畢加索項目提出問題。我沒有看到你有什麼特別的問題。 – CommonsWare

回答

2

您必須爲每個Target保留一個參考,否則當垃圾收集器被調用時系統會自動釋放它們。

因此,更好的解決方案是將每個目標添加到HashSet,然後從Target中的onBitmapLoaded()onBitmapFailed方法中,從目標中移除目標本身。

10

您必須爲每個目標保留一個引用,否則系統 會在調用垃圾回收器時自動釋放它們。

所以,更好的解決方案是每個目標添加到HashSet,然後在 onBitmapLoaded()和onBitmapFailed從目標方法,從該組中刪除 目標本身。

謝謝你的建議,現在我的代碼工作完美。在實現您的建議的代碼片段下面。

[...]//Global var 
    private Set<PoiTarget> poiTargets = new HashSet<PoiTarget>(); 
[...]  
private void somewhere(){ 
    PoiTarget pt; 
    for(Item item: data) { 
     m = map.addMarker(new MarkerOptions() 
       .position(new LatLng(item.latitude, item.longitude)) 
       .title(item.title)); 
     pt = new PoiTarget(m); 
     poiTargets.add(pt); 
     Picasso.with(context) 
      .load(mapImageURLString) 
      .into(pt); 
    } 
} 
[...] 
//-------------------------------------------------------- 
// Inner class 
//-------------------------------------------------------- 
    class PoiTarget implements Target{ 
     private Marker m; 

     public PoiTarget(Marker m) { this.m = m; } 

     @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { 
      m.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap)); 
      poiTargets.remove(this); 
      Tools.msg(" @+ Set bitmap for "+m.getTitle()+" PT size: #"+poiTargets.size()); 
     } 

     @Override public void onBitmapFailed(Drawable errorDrawable) { 
      Tools.msg(" @+ [ERROR] Don't set bitmap for "+m.getTitle()); 
      poiTargets.remove(this); 
     } 

     @Override public void onPrepareLoad(Drawable placeHolderDrawable) { 

     } 
    } 
+1

與畢加索2.4.0目標正在使用這種技術進行垃圾回收。你有任何建議來解決它嗎? – Imanol

+0

這適用於畢加索2.3.2。之前不知道如何使用Target! – Robert