2013-08-31 27 views
8

Dodaję znaczniki na mapie, aby z adresu URL za pomocą Picasso libraryDodawanie znaczników z URL z Picasso

jako marker nie jest ImageView Próbowałem użyć cel zamiast

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 Robię to w pętli, aby dodać około 20 znaczników, ale uważam, że przy pierwszym uruchomieniu kodu dodawane są tylko znaczniki 5 lub 7, więc przełączyłem się na używanie biblioteki lib i AsyncTask w ten sposób.

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(); 
     } 
    } 
} 

Jednak jestem trochę zaniepokojony ta metoda może dać mi jakieś problemy, kiedy mam dużo markerów powiedzieć o 100. Moje pytanie byłoby to jest najlepszym sposobem, aby to zrobić, a jeśli nie to, co inne opcje mogą Próbuję.

+0

Skoncentruję się na debugowaniu pierwszego podejścia. Użyj punktów przerwania lub instrukcji rejestrowania, aby określić, gdzie nie można uzyskać znaczników. – CommonsWare

+0

Użyłem instrukcji rejestrowania w metodach onSucess i onError override obiektu docelowego, także tuż przed wywołaniem klasy Picasso. Logi pokazały, że wygląd był wywoływany 20 razy, onSucess został wywołany kilka razy i onError nigdy nie zadzwonił. –

+0

Jake właśnie wydał wczoraj Picasso 2.0.0 - możesz spróbować, jeśli jeszcze tego nie zrobiłeś. W przeciwnym razie możesz spróbować utworzyć powtarzalny przypadek testowy i zgłosić problem z projektem Picasso. Nie widzę konkretnego problemu z tym, co masz. – CommonsWare

Odpowiedz

2

Musisz zachować referencję dla każdego Target, w przeciwnym razie system automatycznie zwolni je, gdy wywoływacz zostanie wywołany.

Zatem lepszym rozwiązaniem jest dodanie każdego celu do metody HashSet, a następnie onBitmapLoaded() i onBitmapFailed z obiektu docelowego, usunięcie samego obiektu docelowego ze zbioru.

10

Musisz zachować referencję dla każdego celu, w przeciwnym razie system automatycznie zwolni je, gdy wywoływacz zostanie wywołany.

Dlatego lepszym rozwiązaniem jest dodanie do każdego celu HashSet a następnie w onBitmapLoaded() i onBitmapFailed metod Target, usuń Kieruj się z zestawu.

Dziękuję za sugestię, teraz mój kod działa idealnie. Poniżej fragmenty kodu, które implementują Twoją sugestię.

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

W Picasso 2.4.0 cele są śmieci zbierane za pomocą tej techniki. Czy masz jakieś porady, aby to naprawić? – Imanol

+0

To działa dla Picasso 2.3.2. Nie wiedziałem, jak używać tego celu w ten sposób! – Robert