Pytanie Leniwe ładowanie obrazów w ListView


Używam ListView aby wyświetlić niektóre obrazy i podpisy powiązane z tymi obrazami. Dostaję obrazy z Internetu. Czy istnieje sposób na leniwy ładowanie obrazów, więc podczas wyświetlania tekstu interfejs użytkownika nie jest blokowany, a obrazy są wyświetlane po ich pobraniu?

Całkowita liczba zdjęć nie jest stała.


1733
2018-02-12 15:59


pochodzenie


Możesz użyć AsyncImageView GreenDroid. Zadzwoń setUrl. - Pascal Dimassimo
Użyłem tego. To wspaniała realizacja. Złe wieści, że AsyncImageView jest częścią dużego projektu GreenDroid, który sprawia, że ​​twoja aplikacja jest szersza nawet w przypadku, gdy potrzebujesz tylko AsyncImageView. Wygląda na to, że projekt GreenDroid nie jest aktualizowany od 2011 roku. - borisstr
Możesz nawet spróbować tej biblioteki: Android-http-image-manager który moim zdaniem jest najlepszy do asynchronicznego ładowania obrazów. - Ritesh Kumar Dubey
Po prostu skorzystaj z Picassa, zrobi wszystko sam. "Picasso.z (yourContext) .load (img src / path / drawable here) .into (imageView, czyli twój cel);" To jest to! - Anuj Sharma
spróbuj użyć:github.com/nostra13/Android-Universal-Image-Loader , ta biblioteka jest bardzo szybka i wydajna dla leniwego ładowania i buforowania obrazu - krunal patel


Odpowiedzi:


Oto co stworzyłem, aby przechowywać obrazy, które obecnie wyświetla moja aplikacja. Zwróć uwagę, że obiekt "Log" w użyciu jest tutaj moim niestandardowym opakowaniem wokół ostatecznej klasy dziennika w systemie Android.

package com.wilson.android.library;

/*
 Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
*/
import java.io.IOException;

public class DrawableManager {
    private final Map<String, Drawable> drawableMap;

    public DrawableManager() {
        drawableMap = new HashMap<String, Drawable>();
    }

    public Drawable fetchDrawable(String urlString) {
        if (drawableMap.containsKey(urlString)) {
            return drawableMap.get(urlString);
        }

        Log.d(this.getClass().getSimpleName(), "image url:" + urlString);
        try {
            InputStream is = fetch(urlString);
            Drawable drawable = Drawable.createFromStream(is, "src");


            if (drawable != null) {
                drawableMap.put(urlString, drawable);
                Log.d(this.getClass().getSimpleName(), "got a thumbnail drawable: " + drawable.getBounds() + ", "
                        + drawable.getIntrinsicHeight() + "," + drawable.getIntrinsicWidth() + ", "
                        + drawable.getMinimumHeight() + "," + drawable.getMinimumWidth());
            } else {
              Log.w(this.getClass().getSimpleName(), "could not get thumbnail");
            }

            return drawable;
        } catch (MalformedURLException e) {
            Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
            return null;
        } catch (IOException e) {
            Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
            return null;
        }
    }

    public void fetchDrawableOnThread(final String urlString, final ImageView imageView) {
        if (drawableMap.containsKey(urlString)) {
            imageView.setImageDrawable(drawableMap.get(urlString));
        }

        final Handler handler = new Handler() {
            @Override
            public void handleMessage(Message message) {
                imageView.setImageDrawable((Drawable) message.obj);
            }
        };

        Thread thread = new Thread() {
            @Override
            public void run() {
                //TODO : set imageView to a "pending" image
                Drawable drawable = fetchDrawable(urlString);
                Message message = handler.obtainMessage(1, drawable);
                handler.sendMessage(message);
            }
        };
        thread.start();
    }

    private InputStream fetch(String urlString) throws MalformedURLException, IOException {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpGet request = new HttpGet(urlString);
        HttpResponse response = httpClient.execute(request);
        return response.getEntity().getContent();
    }
}

1017
2018-02-18 03:56



Myślę, że powinieneś użyć SoftReferences, aby Twój program nigdy nie powodował OutOfMemoryException. Ponieważ GC może usuwać softreferencje, gdy zwiększa się rozmiar sterty ... możesz zarządzać własnym pokoleniem, tak jak po kilku sekundach możesz umieścić swoje obrazy na tej liście, a przed załadowaniem powinieneś sprawdzić, czy jeśli obraz istnieje, nie pobieraj go ponownie, a raczej zbieraj z tej listy, a także umieszczając go z powrotem na liście softref, a po pewnym czasie możesz oczyścić swoją twardą listę :) - AZ_
Projekt Google Shelves to doskonały przykład tego, jak to się stało code.google.com/p/shelves - AZ_
Czy nie przegapisz powrotu, gdy drawableMap zawiera obraz ... bez uruchamiania wątku pobierania? - Karussell
Ten kod ma kilka problemów. Najpierw powinieneś buforować Drawables, co spowoduje wyciek pamięci: stackoverflow.com/questions/7648740/... . Po drugie sama pamięć podręczna nigdy nie zostanie wyczyszczona, więc będzie rosnąć wiecznie, to kolejny wyciek pamięci. - satur9nine
nikt o tym nie słyszał LRU Cache  developer.android.com/training/displaying-bitmaps/... - Muhammad Babar


zrobiłem proste pokazanie leniwej listy (znajduje się na GitHub) z obrazami. To może być pomocne dla kogoś. Pobiera obrazy w wątku tła. Obrazy są zapisywane w pamięci podręcznej na karcie SD i w pamięci. Implementacja pamięci podręcznej jest bardzo prosta i wystarcza tylko dla wersji demonstracyjnej. Odszyfrowuję obrazy za pomocą inSampleSize, aby zmniejszyć zużycie pamięci. Staram się również poprawnie przetwarzać widoki z recyklingu.

Alt text


983
2018-06-18 08:04



Dziękuję, używam nieznacznie zmodyfikowanej wersji Twojego kodu prawie wszędzie w moim projekcie: code.google.com/p/vimeoid/source/browse/apk/src/com/fedorvlasov/... - shaman.sir
Czy ktoś spojrzał na kod przez Gilles Debunne jako alternatywa. Dwie duże różnice, które widzę to 1) w pamięci podręcznej vs karta SD i 2) użycie AsyncTasks zamiast puli wątków. android-developers.blogspot.com/2010/07/... - Richard
Występuje błąd, czasami jest uruchamiany: 10-13 09: 58: 46.738: BŁĄD / AndroidRuntime (24250): Nieprzytwierdzony program obsługi: wątek główny wychodzący z powodu niezapisanego wyjątku 10-13 09: 58: 46.768: BŁĄD / AndroidRuntime (24250) : java.lang.ArrayIndexOutOfBoundsException: Indeks tablicy poza zakresem: 0 10-13 09: 58: 46.768: BŁĄD / AndroidRuntime (24250): na java.util.Vector.elementAt (Vector.java:331) 10-13 09: 58: 46.768: ERROR / AndroidRuntime (24250): at java.util.Vector.get (Vector.java: 445) 10-13 09: 58: 46.768: ERROR / AndroidRuntime (24250): at com.my.app.image .ImageLoader $ PhotosQueue.Clean (ImageLoader.java:91) - Mikooos
Chciałbym dodać dla początkujących, takich jak ja, że ​​jeśli chcesz dodać ten kod do własnego projektu, musisz dodać uprawnienia zewnętrznego bufora podręcznego do manifestu. Dziękuję Ci - Adam
@BruceHill W najnowszym kodzie źródłowym nie ma photosQueue. Wygląda na to, że używasz bardzo starej wersji. - Fedor


Polecam instrument typu open source Universal Image Loader. Pierwotnie opiera się na projekcie Fedora Własowa Leniwa Lista i od tego czasu znacznie się poprawiła.

  • Ładowanie obrazu wielowątkowego
  • Możliwość szerokiego dostosowania konfiguracji ImageLoadera (executory wątków, downlaoder, dekoder, pamięć podręczna i pamięć dyskowa, opcje wyświetlania obrazu i inne)
  • Możliwość buforowania obrazu w pamięci i / lub w systemie plików urządzenia (lub karty SD)
  • Możliwość "wsłuchiwania" w proces ładowania
  • Możliwość dostosowania każdego wywołania obrazu wyświetlanego z oddzielnymi opcjami
  • Obsługa widgetów
  • Obsługa Androida 2.0+


530
2017-12-19 13:53



jeśli szukasz świetnego kodu "ładującego obraz", który jego twórca traktuje i zachowuje jako swoje cenne dziecko (nie tylko jednorazowe rozwiązanie), właśnie to znalazłeś; Wielkie losy Nostra - AndroidGecko
Naprawdę wspaniała praca, ale to trochę opóźnia mój listview. Gdybyś mógł powiedzieć najlepszą kompilację "ImageLoader", a może dlatego, że "DisplayImageOptions". - dinigo
Bardzo podoba mi się to gridview, ale nie mogę go użyć do mojego samouczka. Jestem początkującym androidem. Robię aplikację o gridview, ale moja aplikacja była targetSdkVersion 15, więc muszę użyć Asynctask do przetworzenia w wątku w tle. Używałem tego widoku siatki, ale to nie działa. jak mogę go używać w targetSdkVersion 15? - kongkea
Możesz utworzyć osobne pytanie z tagiem [Universal-image-loader] - NOSTRA
Po przeczytaniu oficjalnych dokumentów na Androida i próbach zrobienia tego samemu, jestem przekonany, że ta biblioteka to koniec całego procesu ładowania obrazu. Nie udało się zdobyć wystarczającej ilości głosów. - Core


Wielowątkowość dla wydajności, samouczek Gilles Debunne.

To pochodzi z Blogu programistów Androida. Sugerowany kod używa:

  • AsyncTasks.
  • Twardy, ograniczony rozmiar, FIFO cache.
  • Miękki, łatwo garbage collect-ed cache.
  • ZA symbol zastępczy  Drawable podczas pobierania.

enter image description here


147
2017-08-12 11:07



Ale jest zbudowany na systemie Android 2.2 (Froyo) ... - Adinia
Działa również dobrze w wersji 2.1. Po prostu nie używaj AndroidHttpClient. - Thomas Ahle
@ thomas-ahle Dziękuję, widziałem, że AndroidHttpClient podawał błędy w wersji 2.1, ponieważ został zaimplementowany z wersji 2.2, ale tak naprawdę nie próbował znaleźć czegoś, co mógłby go zastąpić. - Adinia
@Adina Masz rację, zapomniałem. Jednak w przepisie nie ma nic, czego nie można równie dobrze zrobić z normalnym HttpClient. - Thomas Ahle
Nadal OOM pozostaje ... - Andro Selva


Aktualizacja: Zauważ, że ta odpowiedź jest teraz całkiem nieskuteczna. Garbage Collector działa agresywnie na SoftReference i WeakReference, więc ten kod NIE jest odpowiedni dla nowych aplikacji.  (Zamiast tego spróbuj bibliotek takich jak Universal Image Loader sugerowane w innych odpowiedziach.)

Podziękowania dla Jamesa za kod oraz Bao-Long za sugestię użycia SoftReference. Zaimplementowałem zmiany SoftReference na kodzie Jamesa. Niestety SoftReferences spowodowało, że moje obrazy zostały zbyt szybko zebrane. W moim przypadku wszystko było w porządku bez rzeczy SoftReference, ponieważ mój rozmiar listy jest ograniczony, a moje obrazy są małe.

Od roku jest dyskusja dotycząca SoftReferences w grupach google: link do wątku. Jako rozwiązanie problemu zbyt wczesnego usuwania śmieci sugerują one możliwość ręcznego ustawienia wielkości sterty maszyny wirtualnej za pomocą metody dalvik.system.VMRuntime.setMinimumHeapSize (), co nie jest dla mnie zbyt atrakcyjne.

public DrawableManager() {
    drawableMap = new HashMap<String, SoftReference<Drawable>>();
}

public Drawable fetchDrawable(String urlString) {
    SoftReference<Drawable> drawableRef = drawableMap.get(urlString);
    if (drawableRef != null) {
        Drawable drawable = drawableRef.get();
        if (drawable != null)
            return drawable;
        // Reference has expired so remove the key from drawableMap
        drawableMap.remove(urlString);
    }

    if (Constants.LOGGING) Log.d(this.getClass().getSimpleName(), "image url:" + urlString);
    try {
        InputStream is = fetch(urlString);
        Drawable drawable = Drawable.createFromStream(is, "src");
        drawableRef = new SoftReference<Drawable>(drawable);
        drawableMap.put(urlString, drawableRef);
        if (Constants.LOGGING) Log.d(this.getClass().getSimpleName(), "got a thumbnail drawable: " + drawable.getBounds() + ", "
                + drawable.getIntrinsicHeight() + "," + drawable.getIntrinsicWidth() + ", "
                + drawable.getMinimumHeight() + "," + drawable.getMinimumWidth());
        return drawableRef.get();
    } catch (MalformedURLException e) {
        if (Constants.LOGGING) Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
        return null;
    } catch (IOException e) {
        if (Constants.LOGGING) Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
        return null;
    }
}

public void fetchDrawableOnThread(final String urlString, final ImageView imageView) {
    SoftReference<Drawable> drawableRef = drawableMap.get(urlString);
    if (drawableRef != null) {
        Drawable drawable = drawableRef.get();
        if (drawable != null) {
            imageView.setImageDrawable(drawableRef.get());
            return;
        }
        // Reference has expired so remove the key from drawableMap
        drawableMap.remove(urlString);
    }

    final Handler handler = new Handler() {
        @Override
        public void handleMessage(Message message) {
            imageView.setImageDrawable((Drawable) message.obj);
        }
    };

    Thread thread = new Thread() {
        @Override
        public void run() {
            //TODO : set imageView to a "pending" image
            Drawable drawable = fetchDrawable(urlString);
            Message message = handler.obtainMessage(1, drawable);
            handler.sendMessage(message);
        }
    };
    thread.start();
}

102
2018-05-05 13:16



możesz tworzyć pokolenia, takie jak hard-generation i softgeneration. możesz naprawić czas wyczyścić pamięć podręczną wyczyści wszystkie obrazy, które nie były dostępne w 3 sekundy .. możesz rzucić okiem na projekt półki google - AZ_
developer.android.com/reference/java/lang/ref/... Dokumentacja SoftReference ma zapis o buforowaniu, zobacz sekcję "Unikaj miękkich odwołań do buforowania". Większość aplikacji powinna używać android.util.LruCache zamiast miękkich odniesień. - vokilam
Podziwiam twój kod, ale teraz w nowym Androidzie O / S jest "agresywne" zbieranie śmieci. Trzymanie słabego odniesienia nie ma dla mnie żadnego sensu. - j2emanue
@ j2emanue Masz rację, jak próbowałem wskazać na górze mojej odpowiedzi, SoftReferences to zbyt szybko zbierane śmieci. Spróbuję edytować tę odpowiedź, aby było jeszcze jaśniejsze. - TalkLittle


Picasso 

Użyj biblioteki Picassa autorstwa Jake'a Whartona. (Idealna biblioteka ImageLoading od dewelopera ActionBarSherlock)

Potężna biblioteka pobierania i buforowania obrazów dla Androida.

Obrazy dodają bardzo potrzebny kontekst i wizualny styl aplikacjom Android. Picasso pozwala na bezproblemowe ładowanie obrazu w aplikacji - często w jednym wierszu kodu!

Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);

Wiele typowych pułapek wczytywania obrazów na Androida jest obsługiwanych automatycznie przez Picasso:

Obsługa recyklingu ImageView i anulowanie pobierania w adapterze. Złożone transformacje obrazu przy minimalnym wykorzystaniu pamięci. Automatyczne buforowanie pamięci i dysku.

Biblioteka Picassa Jake'a Whartona

Poślizg

Glide to szybka i wydajna platforma zarządzania multimediami open source dla systemu Android, która opakowuje dekodowanie multimediów, pamięć podręczną i buforowanie pamięci oraz łączenie zasobów w prosty i łatwy w użyciu interfejs.

Glide obsługuje pobieranie, dekodowanie i wyświetlanie zdjęć, obrazów i animowanych plików GIF. Glide zawiera elastyczne API, które pozwala programistom podłączyć się do niemal każdego stosu sieciowego. Domyślnie Glide używa niestandardowego stosu opartego na HttpUrlConnection, ale zawiera także wtyczki bibliotek narzędziowych do projektu Google Volley lub biblioteki OkHttp Square.

Glide.with(this).load("http://goo.gl/h8qOq7").into(imageView);

Głównym celem Glide jest sprawienie, aby przewijanie listy obrazów było możliwie jak najsprawniejsze i szybkie, ale Glide działa również prawie w każdym przypadku, w którym trzeba pobrać, zmienić rozmiar i wyświetlić zdalny obraz.

Glide Image Loading Library

Fresco na Facebooku 

Fresco to potężny system do wyświetlania obrazów w aplikacjach Android.

Fresco dba o ładowanie i wyświetlanie obrazu, więc nie musisz tego robić. Załaduje obrazy z sieci, pamięci lokalnej lub zasobów lokalnych i wyświetla symbol zastępczy, dopóki obraz nie dotrze. Ma dwa poziomy pamięci podręcznej; jeden w pamięci, a drugi w pamięci wewnętrznej.

Fresco Github

W Androidzie 4.x i niższych Fresco umieszcza obrazy w specjalnym regionie pamięci Android. Pozwala to na szybsze działanie aplikacji i znacznie rzadziej przeraża OutOfMemoryError.

Dokumentacja Fresco


84
2018-04-04 12:35



Picasso to biblioteka opracowana przez Square - LordRaydenMK


Ładowarka o wysokiej wydajności - po zbadaniu sugerowanych tutaj metod, użyłem Ben's solution z pewnymi zmianami -

  1. Zdałem sobie sprawę, że praca z rysunkami jest szybsza niż w przypadku bitmap, więc zamiast tego używam rysunków

  2. Używanie SoftReference jest świetne, ale powoduje, że obraz w pamięci podręcznej jest usuwany zbyt często, dlatego dodałem listę Linked, która zawiera odniesienia do obrazów, zapobiegając usunięciu obrazu, dopóki nie osiągnie zdefiniowanego rozmiaru

  3. Aby otworzyć InputStream, użyłem java.net.URLConnection, co pozwala mi korzystać z pamięci podręcznej stron internetowych (najpierw musisz ustawić pamięć podręczną odpowiedzi, ale to już inna historia)

Mój kod:

import java.util.Map; 
import java.util.HashMap; 
import java.util.LinkedList; 
import java.util.Collections; 
import java.util.WeakHashMap; 
import java.lang.ref.SoftReference; 
import java.util.concurrent.Executors; 
import java.util.concurrent.ExecutorService; 
import android.graphics.drawable.Drawable;
import android.widget.ImageView;
import android.os.Handler;
import android.os.Message;
import java.io.InputStream;
import java.net.MalformedURLException; 
import java.io.IOException; 
import java.net.URL;
import java.net.URLConnection;

public class DrawableBackgroundDownloader {    

private final Map<String, SoftReference<Drawable>> mCache = new HashMap<String, SoftReference<Drawable>>();   
private final LinkedList <Drawable> mChacheController = new LinkedList <Drawable> ();
private ExecutorService mThreadPool;  
private final Map<ImageView, String> mImageViews = Collections.synchronizedMap(new WeakHashMap<ImageView, String>());  

public static int MAX_CACHE_SIZE = 80; 
public int THREAD_POOL_SIZE = 3;

/**
 * Constructor
 */
public DrawableBackgroundDownloader() {  
    mThreadPool = Executors.newFixedThreadPool(THREAD_POOL_SIZE);  
}  


/**
 * Clears all instance data and stops running threads
 */
public void Reset() {
    ExecutorService oldThreadPool = mThreadPool;
    mThreadPool = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
    oldThreadPool.shutdownNow();

    mChacheController.clear();
    mCache.clear();
    mImageViews.clear();
}  

public void loadDrawable(final String url, final ImageView imageView,Drawable placeholder) {  
    mImageViews.put(imageView, url);  
    Drawable drawable = getDrawableFromCache(url);  

    // check in UI thread, so no concurrency issues  
    if (drawable != null) {  
        //Log.d(null, "Item loaded from mCache: " + url);  
        imageView.setImageDrawable(drawable);  
    } else {  
        imageView.setImageDrawable(placeholder);  
        queueJob(url, imageView, placeholder);  
    }  
} 


private Drawable getDrawableFromCache(String url) {  
    if (mCache.containsKey(url)) {  
        return mCache.get(url).get();  
    }  

    return null;  
}

private synchronized void putDrawableInCache(String url,Drawable drawable) {  
    int chacheControllerSize = mChacheController.size();
    if (chacheControllerSize > MAX_CACHE_SIZE) 
        mChacheController.subList(0, MAX_CACHE_SIZE/2).clear();

    mChacheController.addLast(drawable);
    mCache.put(url, new SoftReference<Drawable>(drawable));

}  

private void queueJob(final String url, final ImageView imageView,final Drawable placeholder) {  
    /* Create handler in UI thread. */  
    final Handler handler = new Handler() {  
        @Override  
        public void handleMessage(Message msg) {  
            String tag = mImageViews.get(imageView);  
            if (tag != null && tag.equals(url)) {
                if (imageView.isShown())
                    if (msg.obj != null) {
                        imageView.setImageDrawable((Drawable) msg.obj);  
                    } else {  
                        imageView.setImageDrawable(placeholder);  
                        //Log.d(null, "fail " + url);  
                    } 
            }  
        }  
    };  

    mThreadPool.submit(new Runnable() {  
        @Override  
        public void run() {  
            final Drawable bmp = downloadDrawable(url);
            // if the view is not visible anymore, the image will be ready for next time in cache
            if (imageView.isShown())
            {
                Message message = Message.obtain();  
                message.obj = bmp;
                //Log.d(null, "Item downloaded: " + url);  

                handler.sendMessage(message);
            }
        }  
    });  
}  



private Drawable downloadDrawable(String url) {  
    try {  
        InputStream is = getInputStream(url);

        Drawable drawable = Drawable.createFromStream(is, url);
        putDrawableInCache(url,drawable);  
        return drawable;  

    } catch (MalformedURLException e) {  
        e.printStackTrace();  
    } catch (IOException e) {  
        e.printStackTrace();  
    }  

    return null;  
}  


private InputStream getInputStream(String urlString) throws MalformedURLException, IOException {
    URL url = new URL(urlString);
    URLConnection connection;
    connection = url.openConnection();
    connection.setUseCaches(true); 
    connection.connect();
    InputStream response = connection.getInputStream();

    return response;
}
}

77
2017-12-27 23:27



Działa świetnie! Przy okazji jest literówka w nazwie klasy. - Mullins
W przypadku, gdy komuś oszczędza czas: import java.util.Map; import java.util.HashMap; import java.util.LinkedList; import java.util.Collections; import java.util.WeakHashMap; import java.lang.ref.SoftReference; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; import android.graphics.drawable.Drawable; import android.widget.ImageView; import android.os.Handler; import android.os.Message; import java.io.InputStream; import java.net.MalformedURLException; import java.io.IOException; import java.net.URL; import java.net.URLConnection; - Michael Reed
Wielkie dzięki, to jest miła realizacja. Dodałem również inny symbol zastępczy podczas ładowania szuflady, aby użytkownik mógł uzyskać pewne informacje zwrotne. - Juan Hernandez
Również myślę, że lepiej jest użyć kolejki LIFO w executorService (mThreadPool) zamiast domyślnego FIFO, więc ostatnio żądane obrazy (które prawdopodobnie są widoczne) są ładowane jako pierwsze. Widzieć stackoverflow.com/questions/4620061/how-to-create-lifo-executor - Juan Hernandez
@MichaelReed, na wypadek, gdybyś był użytkownikiem Eclipse, polecam używanie Ctrl-Shift-O (to jest litera O, a nie cyfra 0). Automatyzuje proces dodawania importu i organizuje je dla Ciebie. Jeśli używasz komputera Mac, użyj zamiast niego Command-Shift-O. - SilithCrowe


Śledziłem to szkolenie Android i myślę, że robi doskonałą robotę przy pobieraniu obrazów bez blokowania głównego interfejsu użytkownika. Obsługuje także buforowanie i radzenie sobie z przewijaniem wielu obrazów: Bezpieczne ładowanie dużych bitmap


75
2018-05-22 06:00



Przykro mi, ale wskazałem tylko jedną klasę dla aplikacji Google IO (i jestem za późno na edycję). Powinieneś naprawdę przestudiować wszystkie ładowanie obrazów i caching klasy narzędzi, które można znaleźć w ten sam pakiet co klasa pamięci podręcznej. - mkuech
Czy ktoś poleciłby pobranie plików DiskLruCache, Image * .java z folderu util aplikacji iosched, aby ułatwić obsługę ładowania / buforowania obrazów w widoku listy? Chodzi mi o to, że zdecydowanie warto śledzić online przewodniki programistów na ten temat, ale te klasy (od iosched) idą trochę dalej z wzorcem. - Gautam