2013-08-31 2 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); 

     } 
    }); 
} 

I «Я делаю это в цикле, чтобы добавить около 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

Я использовал инструкции ведения журнала в методах переопределения onSucess и onError цели, а также перед вызовом класса Picasso. Журналы показали, что внешний вид назывался 20 раз, onSucess назывался несколько раз, а onError никогда не вызывал. –

+0

Джейк только что выпустил Picasso 2.0.0 вчера - вы можете попробовать, если вы еще этого не сделали. В противном случае вы можете попытаться создать воспроизводимый тестовый пример и указать проблему с проектом Picasso. Я не вижу особой проблемы с тем, что у вас есть. – CommonsWare

ответ

2

Вы должны хранить ссылку для каждого Target, иначе система автоматически освобождает их, когда вызывается сборщик мусора.

Таким образом, лучшим решением является добавление каждой цели в HashSet, а затем в onBitmapLoaded() и onBitmapFailed методах из цели, удалите цель из набора.

10

Вы должны хранить ссылку для каждой цели, в противном случае система автоматически освобождает их, когда вызывается сборщик мусора.

Таким образом, лучшим решением является добавление каждый объект в HashSet, а затем в onBitmapLoaded() и onBitmapFailed методы из Target, удалите Таргетинг себя из набора.

Благодарим за предложение, теперь мой код работает отлично. Ниже фрагментов кода, которые реализуют ваше предложение.

[...]//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

С Picasso 2.4.0 цели собираются мусором, используя эту технику. У вас есть какие-то советы, чтобы исправить это? – Imanol

+0

Это подходит для Picasso 2.3.2. Не знал, как использовать Target, как это раньше! – Robert

Смежные вопросы