Lokalne rozwiązanie do buforowania obrazu dla Androida: Square Picasso, Universal Image Loader, Glide, Fresco?

89

Szukam asynchronicznego ładowania obrazu i biblioteki buforowania w systemie Android. Zamierzałem użyć Picassa, ale odkryłem, że Universal Image Loader jest bardziej popularny na GitHub. Czy ktoś wie o tych dwóch bibliotekach? Podsumowanie zalet i wad byłoby świetne.

(Wszystkie moje obrazy są na dysku lokalnie, więc nie potrzebuję sieci, dlatego nie sądzę, aby Volley pasował)

XY
źródło

Odpowiedzi:

80

Aktualizacja wrzesień 2018: Po kilku latach potrzebowałem prawie tego samego dla rozwiązania lokalnego buforowania obrazu. Tym razem UIL nie był aktywnie rozwijany. Porównałem popularne biblioteki i wniosek jest prosty: po prostu użyj Glide. Jest znacznie bardziej wydajny i konfigurowalny. Wiele lat temu musiałem rozwidlić i wprowadzić zmiany w UIL. Glide obsługuje wszystkie moje przypadki użycia w zakresie strategii buforowania i wielu poziomów buforowania rozdzielczości za pomocą niestandardowych kluczy. Po prostu użyj Glide!

Porównanie Koushika Dutty dotyczy głównie testu porównawczego prędkości. Jego post dotyczył tylko bardzo podstawowych rzeczy i nie jest specyficzny dla lokalnych obrazów. Chciałbym podzielić się moimi doświadczeniami z Picassem i UIL po zadaniu pytania. Zarówno Picasso, jak i UIL mogą ładować obrazy lokalne. Najpierw wypróbowałem Picassa i byłem zadowolony, ale później zdecydowałem się przejść na UIL, aby uzyskać więcej opcji dostosowywania.

Picasso:

  • Płynny interfejs Picassa jest fajny. Ale skacząc dookoła z „z”, „do”, „załaduj” właściwie nie wiesz, co jest za sceną. To, co zostało zwrócone, jest mylące.

  • Picasso pozwala określić dokładny rozmiar docelowy. Jest to przydatne, gdy masz problemy z pamięcią lub wydajnością, możesz zamienić jakość obrazu na szybkość.

  • Obrazy są buforowane z rozmiarem w kluczu, jest to przydatne, gdy wyświetlasz obrazy o różnych rozmiarach.

  • Możesz dostosować rozmiar pamięci podręcznej. Ale jego pamięć podręczna dysku jest przeznaczona tylko dla żądań http. W przypadku obrazów lokalnych, jeśli zależy Ci na szybkości ładowania, dobrze jest mieć pamięć podręczną na dysku z miniaturami, więc nie musisz za każdym razem czytać kilku MB na obraz. Picasso nie ma tego mechanizmu zmiany rozmiaru i zapisywania miniatur na dysku.

  • Picasso nie ujawnia dostępu do swojej instancji pamięci podręcznej. (Możesz go zdobyć, kiedy po raz pierwszy skonfigurujesz Picassa i trzymasz go w pobliżu ...).

  • Czasami chcesz asynchronicznie wczytać obraz do mapy bitowej zwróconej przez nasłuchiwanie. O dziwo, Picasso tego nie ma. "fetch ()" nie przekazuje niczego. „get ()” służy do odczytu synchronicznego, a „load ()” do asynchronicznego rysowania widoku.

  • Picasso ma tylko kilka prostych przykładów na stronie głównej, a do zaawansowanych zastosowań będziesz musiał przeczytać nieuporządkowany javadoc.

UIL:

  • UIL używa konstruktorów do dostosowywania. Prawie wszystko można skonfigurować.

  • UIL nie pozwala na określenie rozmiaru, który chcesz załadować do widoku. Używa pewnych reguł opartych na wielkości widoku. Nie jest tak elastyczny jak Picasso. Nie mam możliwości załadowania obrazu o niższej rozdzielczości, aby zmniejszyć zużycie pamięci. (Edycja: to zachowanie można łatwo zmodyfikować, dodając argument ImageSize w kodzie źródłowym i omijając sprawdzanie rozmiaru widoku)

  • UIL zapewnia konfigurowalną pamięć podręczną dysku, której można użyć do buforowania miniatur o określonym rozmiarze. Ale to nie jest idealne. Oto szczegóły . (Edycja: jeśli zależy Ci na szybkości i chcesz mieć wiele poziomów pamięci podręcznej miniatur, tak jak w moim przypadku, możesz zmodyfikować kod źródłowy, pozwolić pamięci podręcznej dysku na użycie „memoryKey” i sprawić, by był również wrażliwy na rozmiar)

  • UIL domyślnie buforuje obrazy o różnych rozmiarach w pamięci i można go wyłączyć w konfiguracji.

  • UIL ujawnia pamięć zapasową i dyskową pamięć podręczną, do których masz dostęp.

  • UIL zapewnia elastyczne sposoby pobierania mapy bitowej lub ładowania do widoku.

  • UIL jest lepszy w dokumentacji. UIL zawiera szczegółowe informacje na temat zastosowań na stronie Github i zawiera link do samouczka.

Proponuję zacząć od Picassa, jeśli potrzebujesz większej kontroli i dostosowywania, przejdź do UIL.

XY
źródło
Właściwie utknąłem pomiędzy nimi obiema ... Zasadniczo zamierzam przywrócić obrazy z mojego serwera przechowywane w tamtym katalogu ... więc przez wywołania http, a następnie zapiszę je do pamięci podręcznej (miniatura i zwykły rozmiar, prawdopodobnie będę przechowywać oba rozmiary w moim katalogu) ... czy Picasso jest więc właściwą drogą?
Lion789
@ Lion789 Picasso wykonuje tylko lokalną pamięć podręczną dla plików lokalnych i używa HttpResponseCache do sieciowej pamięci podręcznej na dysku, musisz się temu przyjrzeć. UIL ma konfigurowalną dyskową pamięć podręczną, możesz wprowadzić niewielkie zmiany, aby zaakceptować inny rozmiar obrazu / miniatur. Może najpierw spróbuj Picassa, jeśli uważasz, że jest zbyt ograniczony, idź na UIL i dostosuj
XY,
Więc Picasso może ładować mniejsze obrazy! Wtedy nie muszę ładować 8-megapikselowych! Dzięki, pomogłeś mi!
Aron Lorincz
Czy możesz odpowiedzieć na to pytanie? stackoverflow.com/questions/35433895/…
Usman Rana
UIL does not allow you to specify the size you want to load into a viewnie jest w 100% public void displayImage(String uri, ImageAware imageAware, DisplayImageOptions options, ImageSize targetSize, ImageLoadingListener listener, ImageLoadingProgressListener progressListener)
poprawny
72

Jeśli przeczytasz ten post na G + autorstwa Kousha, otrzymasz jasne rozwiązania swoich nieporozumień, podsumowałem to, w tym, że Android-Universal-Image-Loader jest zwycięzcą dla twojego wymagania!

  • Picasso ma najładniejszy interfejs API obrazów, jeśli korzystasz z sieci!

  • UrlImageViewHelper + AndroidAsync jest najszybszy. Zabawa z tymi dwoma innymi wspaniałymi bibliotekami naprawdę pokazała, że ​​interfejs API obrazów jest dość przestarzały.

  • Volley jest gładka; Naprawdę podoba mi się ich podłączane transporty zaplecza
    i może w końcu upuścić tam AndroidAsync. Zarządzanie priorytetami żądań
    i anulowaniem jest świetne (jeśli korzystasz z sieci)

  • Android-Universal-Image-Loader jest obecnie najpopularniejszym
    . Wysoce konfigurowalny.

Celem tego projektu jest zapewnienie narzędzia wielokrotnego użytku do asynchronicznego ładowania, buforowania i wyświetlania obrazów. Jest pierwotnie oparty na projekcie Fedora Własowa i od tego czasu został gruntownie odnowiony i ulepszony.

Nadchodzące zmiany w nowej wersji UIL (1.9.2):

Możliwość wywołania ImageLoadera poza wątkiem interfejsu użytkownika Nowy interfejs API pamięci podręcznej dysku (bardziej elastyczny). Nowy LruDiscCache oparty na DiskLruCache Jake'a Whartona.

Biorąc pod uwagę, że cały ten Android-Universal-Image-Loader odpowiada Twoim wymaganiom ( ładowanie obrazów jest lokalnie na dysku )!

LOG_TAG
źródło
Zacząłem od Picassa, a skończyłem przechodząc na Universal, mimo że wszystko zostało w pełni wdrożone. Picasso ma lepszy interfejs API, ale ma też wiele problemów. Ten był ostatnim gwoździem do trumny.
Lisandro
45

Chciałbym podzielić się swoim doświadczeniem z tymi 3 bibliotekami: UIL, Picasso i Volley. Wcześniej korzystałem z UIL, ale potem doszedłem do wniosku, że naprawdę nie mogę go polecić i sugerowałbym zamiast tego użyć Volley lub Picasso, które są opracowane przez bardzo utalentowane zespoły. UIL nie jest wcale zły, ale brakuje mu dbałości o szczegóły, jak w pozostałych dwóch bibliotekach.

Zauważyłem, że UIL jest mniej przyjemny z wydajnością interfejsu użytkownika; ma tendencję do blokowania wątku interfejsu użytkownika bardziej niż Volley czy Picasso. Może to częściowo wynikać z faktu, że UIL nie obsługuje grupowania odpowiedzi obrazu, podczas gdy Picasso i Volley robią to domyślnie.

Ponadto nie podobał mi się system pamięci podręcznej dysku UIL. Chociaż można wybierać między różnymi implementacjami, muszę zwrócić uwagę, że w tej chwili nie ma możliwości ograniczenia pamięci podręcznej dysku UIL zarówno pod względem całkowitego rozmiaru, jak i czasu wygaśnięcia jednostki. Volley i Picasso robią to i domyślnie używają czasu wygaśnięcia zwróconego przez serwer, podczas gdy UIL go ignoruje.

Wreszcie, UIL umożliwia ustawienie globalnej konfiguracji programu ładującego obrazy, która obejmuje wybrane implementacje i ustawienia pamięci podręcznej dysku i pamięci podręcznej oraz inne szczegóły, ale ta konfiguracja zostanie zastosowana wszędzie w Twojej aplikacji. Jeśli więc potrzebujesz większej elastyczności, takiej jak dwie oddzielne dyskowe pamięci podręczne, UIL nie ma możliwości. Z drugiej strony Volley pozwala na posiadanie dowolnej liczby oddzielnych programów ładujących obrazy, z których każdy ma własną konfigurację. Picasso domyślnie używa instancji globalnej, ale umożliwia także tworzenie oddzielnie konfigurowalnych instancji.

Podsumowując: Picasso ma najlepsze API, ale używa globalnej pamięci podręcznej HTTP współużytkowanej przez wszystkie HttpURLConnectioninstancje, co w niektórych przypadkach może być zbyt restrykcyjne. Volley ma najlepszą wydajność i modułowość, ale jest mniej przyjazny dla użytkownika i będzie wymagał napisania własnego modułu lub dwóch, aby działał tak, jak chcesz. Ogólnie poleciłbym ich obu przeciwko UIL.

Edycja (18 grudnia 2014 r.): Rzeczy się zmieniły, odkąd napisałem tę wstępną odpowiedź i uznałem, że konieczne jest jej ulepszenie:

Picasso 2.4 jest jeszcze bardziej konfigurowalny niż starsze wersje, a gdy jest używany z OkHttp (co jest wysoce zalecane), może również używać oddzielnej pamięci podręcznej dysku dla każdej instancji, więc naprawdę nie ma ograniczeń co do tego, co możesz zrobić. Co ważniejsze, zauważyłem, że wydajność Picassa i OkHttp znacznie się poprawiła i moim zdaniem jest to teraz najszybsze rozwiązanie do ładowania obrazów dla Androida, kropka. Należy pamiętać, że w moim kodzie zawsze używam .fit()w połączeniu z .centerCrop()lub w .centerInside()celu zmniejszenia zużycia pamięci i unikam zmiany rozmiaru bitmapy w wątku interfejsu użytkownika. Picasso jest aktywnie rozwijany i wspierany, co z pewnością jest dużym plusem.

Volley nie zmienił się tak bardzo, ale w międzyczasie zauważyłem dwa problemy:

  • Czasami przy dużym obciążeniu niektóre obrazy nie są już ładowane z powodu uszkodzenia pamięci podręcznej dysku.
  • Miniatury wyświetlane w NetworkImageView (z typem skali ustawionym na centerCrop) są dość rozmyte w porównaniu z tym, co otrzymujesz w innych bibliotekach.

Z tych powodów zdecydowałem się przestać używać Volley.

UIL jest nadal powolny (szczególnie pamięć podręczna dysku), a jego interfejs API ma tendencję do częstych zmian.

Przetestowałem także tę nową bibliotekę o nazwie Glide 3, która twierdzi, że jest bardziej zoptymalizowana niż Picasso z interfejsem API podobnym do Picassa. Z mojego osobistego doświadczenia wynika, że ​​jest wolniejszy niż Picasso i Volley podczas żądań sieciowych pod dużym obciążeniem, nawet w połączeniu z OkHttp. Co gorsza, spowodowało to kilka awarii moich aplikacji pod Lollipopem podczas opuszczania aktywności. Nadal ma 2 zalety w stosunku do swoich konkurentów:

  • Obsługuje dekodowanie animowanych plików GIF
  • Umieszcza ostateczne, zmniejszone mapy bitowe w pamięci podręcznej dysku, co oznacza, że ​​odczyt z pamięci podręcznej dysku jest niezwykle szybki.

Wniosek: teraz zalecam używanie Picasso + OkHttp, ponieważ zapewnia to najlepszą elastyczność, interfejs API, wydajność i stabilność. Jeśli potrzebujesz obsługi formatu GIF, możesz również rozważyć Glide.

BladeCoder
źródło
1
Aby zająć się ostatnim punktem w UIL, możesz utworzyć dowolną liczbę różnych ImageLoaderklas i konfiguracji. Musisz tylko podklasować ImageLoaderklasę. Zobacz tutaj: github.com/nostra13/Android-Universal-Image-Loader/issues/…
TalkLittle
Wygląda na włamanie, ale dziękuję za wskazówkę, dobrze wiedzieć.
BladeCoder,
3
Nie mogę powiedzieć, że zgadzam się z sentymentem, używamy tutaj Picassa, mam album z ponad 500 obrazami w wysokiej rozdzielczości i miałem problemy z wydajnością i pamięcią, wypróbowałem UIL i wszystko zostało natychmiast rozwiązane. Było to na minimalnej próbce, która izolowała nasze problemy, które widzieliśmy.
HaMMeReD
Jeśli wyświetlasz obrazy o znacznie wyższej rozdzielczości niż ekran lub wiele miniatur obrazów o wysokiej rozdzielczości, zdecydowanie powinieneś zmniejszyć ich próbkowanie. Myślę, że UIL robi to automatycznie, a Picasso nie, jeśli nie określisz odpowiednich opcji, stąd problemy z pamięcią. Osobiście wolę używać NetworkImageView w Volley, jest to widget, który zmniejsza próbkowanie załadowanego obrazu do jego własnego rozmiaru.
BladeCoder
W UIL klasa DisplayImageOptions może być używana, jeśli nie chcemy zmieniać lub stosować innego przetwarzania na określonym obrazie.
Rahul Rastogi
7

Wdrożyłem aplikację, która powinna stale pobierać i wyświetlać obrazy z internetu. Miałem zamiar zaprogramować mechanizm pamięci podręcznej obrazów, zanim znajomy polecił mi uniwersalny program ładujący obrazy.

UIL jest bardzo dobrze konfigurowalny. Jest tak konfigurowalny, że początkujący może łatwo zrobić coś nie tak. Jednak UIL działał wolno w mojej aplikacji i stał się nieco wolniejszy. Moim przypadkiem użycia był ListView z obrazami.

Wczoraj szukałem alternatywy dla UIL i odkryłem Picassa. Picasso był łatwy w integracji i obsłudze: po prostu, Picasso.context(context).load(url).into(imageview)a obraz można było szybciej i płynnie zintegrować.

Dla mnie Picasso jest zdecydowanie API do użycia. Moje doświadczenia z UIL nie były dobre.

Samuel L.
źródło
Dla przyszłych czytelników: Glide jest lepszy od Picassa. Spójrz
therealprashant
0

Myślę, że ImageLoader jest bardziej konfigurowalny i elastyczny w porównaniu z biblioteką Picassa.

Jin Ding
źródło
8
W jaki sposób? małe wyjaśnienie pomoże.
Darpan,