Jak mogę buforować obrazy po ich pobraniu z sieci?
141
A teraz puenta: użyj pamięci podręcznej systemu.
URL url = new URL(strUrl);
URLConnection connection = url.openConnection();
connection.setUseCaches(true);
Object response = connection.getContent();
if (response instanceof Bitmap) {
Bitmap bitmap = (Bitmap)response;
}
Zapewnia pamięć podręczną i pamięć podręczną flash-rom, współdzielone z przeglądarką.
grr. Żałuję, że ktoś mi to nie powiedział, zanim napisałem własnego menedżera pamięci podręcznej.
connection.getContent()
zawsze zwraca dla mnie InputStream, co robię źle?Bitmap response = BitmapFactory.decodeStream((InputStream)connection.getContent());
Odnośnie eleganckiego
connection.setUseCaches
rozwiązania powyżej: niestety nie zadziała bez dodatkowego wysiłku. Będziesz musiał zainstalowaćResponseCache
usingResponseCache.setDefault
. W przeciwnym razieHttpURLConnection
po cichu zignorujesetUseCaches(true)
bit.Aby
FileResponseCache.java
uzyskać szczegółowe informacje, zobacz komentarze u góry :http://libs-for-android.googlecode.com/svn/reference/com/google/android/filecache/FileResponseCache.html
(Opublikowałbym to w komentarzu, ale najwyraźniej nie mam wystarczająco dużo karmy SOJ).
źródło
HttpResponseCache
, możesz znaleźćHttpResponseCache.getHitCount()
zwracające 0. Nie jestem pewien, ale myślę, że dzieje się tak, ponieważ żądany serwer WWW nie używa w tym przypadku nagłówków pamięci podręcznej. Aby mimo wszystko buforowanie działało, użyjconnection.addRequestProperty("Cache-Control", "max-stale=" + MAX_STALE_CACHE);
..getContent()
metody, ponieważ odpowiedzi 304 nie mają powiązanej treści odpowiedzi według standardu RFC.Przekonwertuj je na mapy bitowe, a następnie zapisz je w kolekcji (mapa haszowania, lista itp.) Lub możesz zapisać je na karcie SD.
Przechowując je w przestrzeni aplikacji przy użyciu pierwszego podejścia, możesz chcieć owinąć je wokół java.lang.ref.SoftReference, szczególnie jeśli ich liczba jest duża (aby były zbierane jako śmieci podczas kryzysu). Może to jednak spowodować przeładowanie.
zapisanie ich na karcie SD nie będzie wymagało ponownego załadowania; tylko zezwolenie użytkownika.
źródło
Uri
odniesienia do ścieżki, do którego można przejść,ImageView
i innych niestandardowych widoków. Ponieważ za każdym razemcompress
będziesz tracić jakość. Oczywiście dotyczy to tylko algorytmów stratnych. Ta metoda umożliwiłaby nawet przechowywanie skrótu pliku i użycie go następnym razem, gdy zażądasz pliku z serwera za pośrednictwemIf-None-Match
iETag
nagłówków.Służy
LruCache
do wydajnego buforowania obrazów. Można przeczytać oLruCache
z Android Developer miejscuUżyłem poniższego rozwiązania do pobierania i buforowania obrazów w systemie Android. Możesz wykonać poniższe czynności:
KROK 1: nadaj klasie nazwę
ImagesCache
. UżyłemSingleton object for this class
KROK 2:
stwórz kolejną klasę o nazwie DownloadImageTask, która jest używana, jeśli bitmapa nie jest dostępna w pamięci podręcznej, pobierze ją stąd:
KROK 3: Użycie z Twojego
Activity
lubAdapter
Uwaga: jeśli chcesz załadować obraz z adresu URL z
Activity
Class. Użyj drugiego Konstruktora zDownloadImageTask
, ale jeśli chcesz wyświetlić obraz zAdapter
użyj pierwszego Konstruktora zDownloadImageTask
(na przykład masz obraz wListView
i ustawiasz obraz z 'Adaptera')WYKORZYSTANIE Z AKTYWNOŚCI:
UŻYCIE Z ADAPTERA:
Uwaga:
cache.initializeCache()
możesz użyć tego stwierdzenia w pierwszym działaniu swojej aplikacji. Po zainicjowaniu pamięci podręcznej nigdy nie będziesz musiał jej inicjować za każdym razem, jeśli używaszImagesCache
instancji.Nigdy nie jestem dobry w wyjaśnianiu rzeczy, ale mam nadzieję, że pomoże to początkującym, jak buforować użycie
LruCache
i jego użycie :)EDYTOWAĆ:
Obecnie istnieją bardzo znane biblioteki znane jako
Picasso
i,Glide
które mogą być używane do bardzo wydajnego ładowania obrazów w aplikacji na Androida. Wypróbuj tę bardzo prostą i użyteczną bibliotekę Picasso na Androida i Glide na Androida . Nie musisz martwić się o obrazy w pamięci podręcznej.Możesz również odwiedzić blog, aby zobaczyć różnicę między Glide i Picasso
źródło
if(cache == null)
co rozwiązało mój problem! :)Aby pobrać obraz i zapisać na karcie pamięci, możesz to zrobić w ten sposób.
Nie zapomnij dodać pozwolenia internetowego do swojego manifestu:
źródło
Rozważałbym użycie pamięci podręcznej obrazu droidfu. Implementuje zarówno pamięć podręczną obrazów w pamięci, jak i na dysku. Otrzymujesz również WebImageView, który korzysta z biblioteki ImageCache.
Oto pełny opis droidfu i WebImageView: http://brainflush.wordpress.com/2009/11/23/droid-fu-part-2-webimageview-and-webgalleryadapter/
źródło
Wypróbowałem SoftReferences, są zbyt agresywnie odzyskiwane w Androidzie, że czułem, że nie ma sensu ich używać
źródło
SoftReference
plików. Zalecają używanie ichLruCache
zamiast tego.Jak zasugerował Thunder Rabbit, ImageDownloader jest najlepszy do tego zadania. Znalazłem też niewielkie zróżnicowanie klasy na:
http://theandroidcoder.com/utilities/android-image-download-and-caching/
Główna różnica między nimi polega na tym, że ImageDownloader używa systemu pamięci podręcznej Androida, a zmodyfikowany wykorzystuje pamięć wewnętrzną i zewnętrzną jako buforowanie, przechowując obrazy w pamięci podręcznej przez czas nieokreślony lub do momentu, gdy użytkownik usunie je ręcznie. Autor wspomina również o kompatybilności z Androidem 2.1.
źródło
To dobry chwyt Joe. Powyższy przykład kodu ma dwa problemy - jeden - obiekt odpowiedzi nie jest instancją Bitmap (kiedy mój adres URL odwołuje się do pliku jpg, np. Http: \ website.com \ image.jpg, jest to plik a
org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl $ LimitedInputStream).
Po drugie, jak wskazuje Joe, żadne buforowanie nie występuje bez skonfigurowania pamięci podręcznej odpowiedzi. Deweloperzy Androida są zmuszeni do rozwijania własnej pamięci podręcznej. Oto przykład, jak to zrobić, ale buforuje tylko w pamięci, co tak naprawdę nie jest pełnym rozwiązaniem.
http://codebycoffee.com/2010/06/29/using-responsecache-in-an-android-app/
Interfejs API buforowania URLConnection opisano tutaj:
http://download.oracle.com/javase/6/docs/technotes/guides/net/http-cache.html
Nadal uważam, że jest to dobre rozwiązanie, aby przejść tę trasę - ale nadal musisz napisać pamięć podręczną. Brzmi fajnie, ale wolałbym pisać funkcje.
źródło
W oficjalnej sekcji szkoleniowej Androida jest na ten temat specjalny wpis: http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
Sekcja jest całkiem nowa, nie było jej tam, kiedy zadano pytanie.
Sugerowanym rozwiązaniem jest użycie LruCache. Ta klasa została wprowadzona w Honeycomb, ale jest również uwzględniona w bibliotece zgodności.
Możesz zainicjować LruCache, ustawiając maksymalną liczbę lub wpisy, a on automatycznie posortuje je według Ciebie i wyczyści rzadziej używane, gdy przekroczysz limit. Poza tym jest używana jako normalna mapa.
Przykładowy kod z oficjalnej strony:
Wcześniej SoftReferences były dobrą alternatywą, ale już nie, cytując z oficjalnej strony:
źródło
Rozważ użycie biblioteki Universal Image Loader autorstwa Sergeya Tarasevicha . Pochodzi z:
Universal Image Loader umożliwia szczegółowe zarządzanie pamięcią podręczną pobranych obrazów z następującymi konfiguracjami pamięci podręcznej:
UsingFreqLimitedMemoryCache
: Najrzadziej używana mapa bitowa jest usuwana po przekroczeniu limitu rozmiaru pamięci podręcznej.LRULimitedMemoryCache
: Najmniej używana mapa bitowa jest usuwana po przekroczeniu limitu rozmiaru pamięci podręcznej.FIFOLimitedMemoryCache
: Reguła FIFO jest używana do usuwania, gdy zostanie przekroczony limit rozmiaru pamięci podręcznej.LargestLimitedMemoryCache
: Największa mapa bitowa jest usuwana po przekroczeniu limitu rozmiaru pamięci podręcznej.LimitedAgeMemoryCache
: Obiekt w pamięci podręcznej jest usuwany, gdy jego wiek przekroczy zdefiniowaną wartość .WeakMemoryCache
: Pamięć podręczna zawierająca tylko słabe odniesienia do map bitowych.Prosty przykład użycia:
W tym przykładzie użyto domyślnej
UsingFreqLimitedMemoryCache
.źródło
To, co faktycznie zadziałało, to ustawienie ResponseCache w mojej klasie głównej:
i
podczas pobierania mapy bitowej.
http://practicaldroid.blogspot.com/2013/01/utilizing-http-response-cache.html
źródło
Google libs-for-android ma ładne biblioteki do zarządzania pamięcią podręczną obrazów i plików.
http://code.google.com/p/libs-for-android/
źródło
Zmagałem się z tym przez jakiś czas; odpowiedzi za pomocą SoftReferences zbyt szybko utraciłyby dane. Odpowiedzi, które sugerują utworzenie wystąpienia RequestCache, były zbyt skomplikowane, a ponadto nigdy nie mogłem znaleźć pełnego przykładu.
Ale ImageDownloader.java działa wspaniale dla mnie. Używa HashMap do momentu osiągnięcia pojemności lub do upływu limitu czasu oczyszczania, a następnie przenosi rzeczy do SoftReference, wykorzystując w ten sposób to, co najlepsze z obu światów.
źródło
Proponuję ZAPŁON to nawet lepiej niż Droid fu
https://github.com/kaeppler/ignition
https://github.com/kaeppler/ignition/wiki/Sample-applications
źródło
Jeszcze później odpowiedź, ale napisałem Menedżera obrazów Androida, który obsługuje buforowanie w sposób przezroczysty (pamięć i dysk). Kod znajduje się na Github https://github.com/felipecsl/Android-ImageManager
źródło
Późne odpowiedź, ale pomyślałem, powinienem dodać link do mojej strony, bo pisałem tutorial jak zrobić bufor obrazu dla android:
http://squarewolf.nl/2010/11/android-image-cache/Aktualizacja: strona została przeniesiona do trybu offline, ponieważ jej źródło było nieaktualne. Dołączam do @elenasys w jej radach dotyczących używania Ignition .A więc do wszystkich ludzi, którzy natknęli się na to pytanie i nie znaleźli rozwiązania: mam nadzieję, że Ci się spodoba! = D
źródło
Późna odpowiedź, ale myślę, że ta biblioteka bardzo pomoże w buforowaniu obrazów: https://github.com/crypticminds/ColdStorage .
Po prostu dodaj adnotację ImageView za pomocą @LoadCache (R.id.id_of_my_image_view, "URL_to_downlaod_image_from), a zajmie się pobieraniem obrazu i ładowaniem go do widoku obrazu. Możesz również określić obraz zastępczy i załadować animację.
Szczegółowa dokumentacja adnotacji znajduje się tutaj: - https://github.com/crypticminds/ColdStorage/wiki/@LoadImage-annotation
źródło