Leniwe ładowanie obrazów w ListView

Używam ListView do wyświetlania niektórych obrazów i podpisów związanych z tymi obrazami. Dostaję zdjęcia z Internetu. Czy istnieje sposób na leniwe ładowanie obrazów, aby podczas wyświetlania tekstu interfejs użytkownika nie był zablokowany, a obrazy są wyświetlane podczas ich pobierania?

Całkowita liczba obrazów nie jest stała.

Author: Pehlaj, 2009-02-12

30 answers

Oto, co stworzyłem, aby trzymać obrazy, które moja aplikacja jest obecnie wyświetlana. Proszę zauważyć, że używany tutaj obiekt "Log" jest moim niestandardowym opakowaniem wokół ostatecznej klasy dziennika w Androidzie.

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();
    }
}
 1030
Author: James A Wilson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-22 19:17:38

Zrobiłem proste demo leniwej listy (znajdującej się na Githubie) z obrazkami. To może komuś pomóc. Pobiera obrazy w wątku tła. Obrazy są buforowane na karcie SD i w pamięci. Implementacja cache jest bardzo prosta i wystarczy na demo. Dekoduję obrazy za pomocą inSampleSize, aby zmniejszyć zużycie pamięci. Staram się również poprawnie radzić sobie z recyclingowymi widokami.

Alt text

 993
Author: Fedor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-28 23:16:51

Polecam instrument open source Universal Image Loader. Jest on pierwotnie oparty na projekcie Fedora Własowa LazyList i został znacznie ulepszony od tego czasu.

  • wielowątkowe ładowanie obrazu
  • [9]}możliwość szerokiego dostrajania konfiguracji Imageloadera (thread executors, downlaoder, dekoder, pamięć podręczna i dysk, opcje wyświetlania obrazu i inne)
  • możliwość buforowania obrazu w pamięci i / lub na sysytem pliku urządzenia (lub SD karta)
  • możliwość" odsłuchania " procesu ładowania
  • możliwość dostosowania każdego wywołania wyświetlania obrazu z oddzielnymi opcjami
  • Obsługa widgetów
  • Android 2.0 + wsparcie

 536
Author: NOSTRA,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-28 23:19:24

Multithreading for Performance , samouczek Gillesa Debunne ' a.

To jest z bloga programistów Androida. Sugerowany kod używa:
  • AsyncTasks.
  • twardy, ograniczony rozmiar, FIFO cache.
  • miękki, łatwy garbage collect-ed cache.
  • a placeholder Drawable podczas pobierania.

Tutaj wpisz opis obrazka

 150
Author: Thomas Ahle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-13 11:45:30

Aktualizacja: zauważ, że ta odpowiedź jest teraz dość 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 typuUniversal Image Loader zasugerowanych w innych odpowiedziach.)

Podziękowania dla Jamesa za kod, i Bao-Long za sugestię użycia SoftReference. Zaimplementowałem zmiany Softreferencyjne w kodzie Jamesa. Niestety Softreferencje sprawiły, że moje zdjęcia stały się śmieciami zebrano zbyt szybko. W moim przypadku było dobrze bez softreference rzeczy, ponieważ mój rozmiar listy jest ograniczony, a moje zdjęcia są małe.

Jest dyskusja sprzed roku dotycząca Softreferencji w google groups: link do wątku . Jako rozwiązanie zbyt wczesnego zbierania śmieci sugerują możliwość ręcznego ustawiania rozmiaru sterty maszyny Wirtualnej za pomocą 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();
}
 104
Author: TalkLittle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-22 00:17:58

Picasso

Użyj Biblioteki Picassa Jake ' a Whartona. (Doskonała Biblioteka ImageLoading tworzona przez twórcę ActionBarSherlock) [2]}potężna biblioteka pobierania i buforowania obrazów dla Androida.

Obrazy dodają bardzo potrzebny kontekst i styl wizualny do aplikacji na Androida. Picasso pozwala na bezproblemowe ładowanie obrazów w aplikacji-często w jednej linii kodu!

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

Wiele typowych pułapek ładowania obrazu na Androida są obsługiwane automatycznie przez Picasso:

Obsługa recyklingu ImageView i anulowania pobierania w adapterze. Złożone przekształcenia obrazu przy minimalnym zużyciu pamięci. Automatyczne buforowanie pamięci i dysku.

Picasso Jake Wharton ' s Library

Glide

Glide to szybki i wydajny framework do zarządzania multimediami dla systemu Android, który owija dekodowanie multimediów, buforowanie pamięci i dysków oraz łączenie zasobów w prosty i łatwy w użyciu interfejs.

Podpory ślizgowe pobieranie, dekodowanie i wyświetlanie zdjęć wideo, obrazów i animowanych plików GIF. Glide zawiera elastyczny interfejs api, który pozwala programistom podłączyć się do niemal każdego stosu sieciowego. Domyślnie Glide używa niestandardowego stosu opartego na HttpUrlConnection, ale zawiera również biblioteki narzędzi wtyczki 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 dowolnej listy obrazów było płynne i szybkie, ale Glide jest również skuteczne w przypadku prawie w każdym przypadku, gdy trzeba pobrać, zmienić rozmiar i wyświetlić Zdalny obraz.

Glide Image Loading Library

Fresco by Facebook

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. Ładuje obrazy z sieci, magazynu lokalnego lub zasobów lokalnych i wyświetla symbol zastępczy do momentu przybycia obrazu. Posiada dwa poziomy pamięci podręcznej; jeden w pamięć i inny w pamięci wewnętrznej.

Fresco Github

W Androidzie 4.x i niższe, fresco umieszcza obrazy w specjalnym obszarze pamięci Androida. Pozwala to aplikacji działać szybciej - i cierpią bał OutOfMemoryError znacznie rzadziej.

Fresco Documentation

 88
Author: Ashwin S Ashok,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-11 18:02:34

[1]}High performance loader - po zapoznaniu się z zaproponowanymi tu metodami, Użyłem Rozwiązania Bena z pewnymi zmianami -

  1. Zdałem sobie sprawę, że praca z drawables jest szybsza niż z bitmapami, więc używam drawables zamiast

  2. Korzystanie z SoftReference jest wielki, ale to sprawia, że buforowany Obraz być usuwane zbyt często, więc dodałem połączoną listę, która zawiera odwołania do obrazów, zapobiegając od obrazu być usuwane, aż osiągnie predefiniowane rozmiar

  3. Aby otworzyć InputStream użyłem java.net. URLConnection, który pozwala mi używać web cache (najpierw musisz ustawić response cache, 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;
}
}
 78
Author: Pinhassi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-14 09:37:15

Śledziłem to szkolenie na Androida i myślę, że świetnie sprawdza się w pobieraniu obrazów bez blokowania głównego interfejsu użytkownika. Obsługuje również buforowanie i radzenie sobie z przewijaniem wielu obrazów: wydajne ładowanie dużych Bitmap

 76
Author: toobsco42,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-02 21:01:16

1. Picasso pozwala na bezproblemowe ładowanie obrazu w aplikacji-często w jednej linijce kodu!

Użyj Gradle:

implementation 'com.squareup.picasso:picasso:2.71828'
Tylko jedna linijka kodu!
Picasso.get().load("http://i.imgur.com/DvpvklR.png").into(imageView);

2. Glide Biblioteka ładowania i buforowania obrazów dla Androida koncentruje się na płynnym przewijaniu

Użyj Gradle:

repositories {
  mavenCentral() 
  google()
}

dependencies {
   implementation 'com.github.bumptech.glide:glide:4.7.1'
   annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'
}

// dla prostego widoku:

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

3. fresco na potężny system do wyświetlania obrazów w Androidzie aplikacje.Fresco dba o ładowanie i wyświetlanie obrazu, dzięki czemu nie masz za.

Pierwsze kroki z Fresco

 58
Author: chiragkyada,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-25 10:58:53

Napisałem tutorial, który wyjaśnia, jak zrobić leniwe ładowanie obrazów w widoku listy. Wnikam w szczegóły dotyczące kwestii recyklingu i współbieżności. Używam również stałej puli wątków, aby zapobiec zrodzeniu wielu wątków.

Leniwe ładowanie obrazów w samouczku Listview

 51
Author: Ben Ruijl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-04 20:40:56

Sposób, w jaki to robię, polega na uruchomieniu wątku, aby pobrać obrazy w tle i przekazać mu wywołanie zwrotne dla każdego elementu listy. Po zakończeniu pobierania obraz wywołuje wywołanie zwrotne, które aktualizuje widok dla elementu listy.

Ta metoda nie działa zbyt dobrze, gdy recyklingujesz widoki.

 39
Author: jasonhudgins,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-12 20:07:14

Chcę tylko dodać jeszcze jeden dobry przykład, Adaptery XML. Ponieważ jest używany przez Google i używam tej samej logiki, aby uniknąć błędu OutOfMemory.

Zasadniczo Ten ImageDownloader jest twoją odpowiedzią (ponieważ pokrywa większość twoich wymagań). Niektóre można również wdrożyć w tym.

 31
Author: Arslan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-22 19:32:50

Używam NetworkImageView z nowej biblioteki Android Volley com.android.volley.toolbox.NetworkImageView i wydaje się, że działa całkiem dobrze. Widocznie jest to ten sam widok, który jest używany w Google Play i innych nowych aplikacjach Google. Zdecydowanie warto to sprawdzić.

 28
Author: droidment,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-16 13:28:38

Jest to powszechny problem na Androidzie, który został rozwiązany na wiele sposobów przez wiele osób. Moim zdaniem najlepszym rozwiązaniem jest stosunkowo nowa biblioteka o nazwie Picasso . Oto najważniejsze wydarzenia:

  • Open source, ale na czele Jake Wharton z ActionBarSherlock fame.
  • asynchronicznie ładuj obrazy z zasobów sieci lub aplikacji za pomocą jednej linii kodu
  • Automatyczne ListView wykrywanie
  • automatyczne buforowanie dysku i pamięci
  • można zrobić transformacje niestandardowe
  • Wiele opcji konfigurowalnych
  • Super proste API
  • często aktualizowane
 27
Author: howettl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-15 23:22:19

Cóż, czas ładowania zdjęć z Internetu ma wiele rozwiązań. Możesz również użyć biblioteki Android-Query . To daje wszystkie wymagane działania. Upewnij się, co chcesz zrobić i przeczytaj stronę wiki biblioteki. I rozwiąż ograniczenie ładowania obrazu.

To jest mój kod:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;
    if (v == null) {
        LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.row, null);
    }

    ImageView imageview = (ImageView) v.findViewById(R.id.icon);
    AQuery aq = new AQuery(convertView);

    String imageUrl = "http://www.vikispot.com/z/images/vikispot/android-w.png";

    aq.id(imageview).progress(this).image(imageUrl, true, true, 0, 0, new BitmapAjaxCallback() {
        @Override
        public void callback(String url, ImageView iv, Bitmap bm, AjaxStatus status) {
            iv.setImageBitmap(bm);
        }
    ));

    return v;
}

Powinno to rozwiązać twój leniwy problem z ładowaniem.

 25
Author: Rahul Rawat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-24 21:10:00

Myślę, że ten problem jest bardzo popularny wśród programistów Androida i jest wiele takich bibliotek, które twierdzą, że rozwiązują ten problem, ale tylko kilka z nich wydaje się być na miejscu. AQuery jest jedną z takich bibliotek, ale pod każdym względem jest lepsza od większości z nich i warto ją wypróbować.

 24
Author: Ritesh Kumar Dubey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-16 13:19:04

Jest to bardzo proste, ale nie jest to łatwe rozwiązanie, ponieważ nie jest to łatwe do zainstalowania. Obsługuje asynchroniczne buforowanie, przechowuje nieudane adresy URL, dobrze obsługuje współbieżność i pomocne podklasy są zawarte.

Żądania pobierania (i zgłoszenia błędów) są również mile widziane!

 20
Author: PatrickNLT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-02 17:42:16

Musisz wypróbować ten uniwersalny ładowacz jest najlepszy. Używam tego po wykonaniu wielu RnD na leniwym ładowaniu .

Universal Image Loader

Cechy

  • wielowątkowe ładowanie obrazu (asynchronizacja lub synchronizacja)
  • szerokie dostosowanie konfiguracji Imageloadera (thread executors, downloader, dekoder, pamięć i pamięć podręczna dysku, opcje wyświetlania obrazu itp.)
  • Wiele opcji dostosowywania dla każdego wywołania obrazu wyświetlania (obrazy stub, przełącznik buforowania, opcje dekodowania, przetwarzania i wyświetlania Bitmap itp.)
  • [11]}buforowanie obrazu w pamięci i / lub na dysku (system plików urządzenia lub karta SD)
  • proces ładowania odsłuchu (w tym postęp pobierania)

Android 2.0 + wsparcie

Tutaj wpisz opis obrazka

 17
Author: Girish Patel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-05 12:45:50

DroidParts ma ImageFetcher , który wymaga zerowej konfiguracji, aby rozpocząć.

  • używa pamięci podręcznej na dysku i w pamięci ostatnio używanej pamięci podręcznej (LRU).
  • skutecznie dekoduje obrazy.
  • obsługuje modyfikowanie bitmap w wątku tła.
  • ma prosty cross-fade.
  • ma wywołanie zwrotne postępu ładowania obrazu.

Klon DroidPartsGram dla przykładu:

Tutaj wpisz opis obrazka

 16
Author: yanchenko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-16 13:26:19

Krótka wskazówka dla kogoś, kto jest niezdecydowany, jakiej biblioteki użyć do leniwego ładowania obrazów:

Istnieją cztery podstawowe sposoby.

  1. DIY = > nie jest to najlepsze rozwiązanie, ale dla kilku obrazów i jeśli chcesz przejść bez kłopotów z używaniem innych bibliotek

  2. Leniwy Loading library = > from guys at android. Jest ładny i w ogóle, ale jest słabo udokumentowany i dlatego jest problem w użyciu.

  3. Picasso: proste rozwiązanie, które po prostu działa, możesz nawet określić dokładny rozmiar obrazu, który chcesz wprowadzić. Jest bardzo prosty w użyciu, ale może nie być bardzo "wydajny" dla aplikacji, które mają do czynienia z ogromną ilością obrazów.

  4. UIL: najlepszy sposób na leniwe ładowanie obrazów. Możesz buforować obrazy (oczywiście potrzebujesz uprawnień), zainicjować ładowarkę raz, a następnie wykonać swoją pracę. Najbardziej dojrzała biblioteka asynchronicznego ładowania obrazów, jaką do tej pory widziałem.

 16
Author: Bijay Koirala,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-02 05:23:43

Novoda ma również wielką bibliotekę lazy image loading i wiele aplikacji, takich jak Songkick, Podio, SecretDJ i ImageSearch korzystać z ich biblioteki.

Ich Biblioteka jest hostowana tutaj na Githubie i mają również dość aktywnyissues tracker . Ich projekt wydaje się być również dość aktywny, z ponad 300+ commitów w momencie pisania tej odpowiedzi.

 15
Author: Soham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-12 11:00:25

Sprawdź mój widelec LazyList . Zasadniczo poprawiam LazyList opóźniając wywołanie ImageView i tworzę dwie metody:

  1. Kiedy trzeba umieścić coś w stylu " ładowanie obrazu..."
  2. Kiedy musisz pokazać pobrany obraz.

Poprawiłem również ImageLoader implementując singleton w tym obiekcie.

 13
Author: Nicolas Jafelle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-16 13:24:50

Wszystkie powyższe kody mają swoją wartość, ale z moim osobistym doświadczeniem po prostu spróbuj z Picassem.

Picasso jest biblioteką specjalnie do tego celu, w rzeczywistości będzie zarządzać buforem i wszystkimi innymi operacjami sieciowymi automatycznie.Będziesz musiał dodać bibliotekę do swojego projektu i po prostu napisać pojedynczą linię kodu, aby załadować obraz ze ZDALNEGO ADRESU URL.

Proszę odwiedzić tutaj: http://code.tutsplus.com/tutorials/android-sdk-working-with-picasso--cms-22149

 11
Author: Akbar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-26 18:54:20

Mogę polecić inny sposób, który działa jak urok: Android Query.

Możesz pobrać plik JAR z tutaj

AQuery androidAQuery = new AQuery(this);

Jako przykład:

androidAQuery.id(YOUR IMAGEVIEW).image(YOUR IMAGE TO LOAD, true, true, getDeviceWidth(), ANY DEFAULT IMAGE YOU WANT TO SHOW);

Jest bardzo szybki i dokładny, a za jego pomocą można znaleźć wiele innych funkcji, takich jak animacja podczas ładowania, uzyskiwanie bitmapy (w razie potrzeby) itp.

 7
Author: Pratik Dasa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-16 13:36:00

Daj Aquery Spróbuj. Posiada niezwykle proste metody ładowania i buforowania obrazów asynchronicznie.

 7
Author: user2779311,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-16 13:37:22

URLImageViewHelper jest niesamowitą biblioteką, która pomaga Ci to zrobić.

 7
Author: DiegoAlt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-16 13:37:45

Użyj biblioteki glide. Zadziałało dla mnie i będzie działać dla Twojego kodu too.It działa zarówno dla obrazów, jak i GIF-ów.

ImageView imageView = (ImageView) findViewById(R.id.test_image); 
    GlideDrawableImageViewTarget imagePreview = new GlideDrawableImageViewTarget(imageView);
    Glide
            .with(this)
            .load(url)
            .listener(new RequestListener<String, GlideDrawable>() {
                @Override
                public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {                       
                    return false;
                }

                @Override
                public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
                    return false;
                }
            })
            .into(imagePreview);
}
 7
Author: Saket Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-16 10:11:09

Jeśli chcesz wyświetlać układ Shimmer, taki jak Facebook, istnieje do tego oficjalna biblioteka Facebooka. FaceBook Shimmer Android

Zajmuje się wszystkim, Wystarczy umieścić żądany kod projektu w sposób zagnieżdżony w ramce shimmer. Oto przykładowy kod.

<com.facebook.shimmer.ShimmerFrameLayout
     android:id=“@+id/shimmer_view_container”
     android:layout_width=“wrap_content”
     android:layout_height="wrap_content"
     shimmer:duration="1000">

 <here will be your content to display />

</com.facebook.shimmer.ShimmerFrameLayout>

A oto kod Javy.

ShimmerFrameLayout shimmerContainer = (ShimmerFrameLayout) findViewById(R.id.shimmer_view_container);
shimmerContainer.startShimmerAnimation();

Dodaj tę zależność do pliku gradle.

implementation 'com.facebook.shimmer:shimmer:0.1.0@aar'
Oto Jak to wygląda.Shimmer Android screenshot
 5
Author: Zankrut Parmar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-26 05:02:17
public class ImageDownloader {

Map<String, Bitmap> imageCache;

public ImageDownloader() {
    imageCache = new HashMap<String, Bitmap>();

}

// download function
public void download(String url, ImageView imageView) {
    if (cancelPotentialDownload(url, imageView)) {

        // Caching code right here
        String filename = String.valueOf(url.hashCode());
        File f = new File(getCacheDirectory(imageView.getContext()),
                filename);

        // Is the bitmap in our memory cache?
        Bitmap bitmap = null;

        bitmap = (Bitmap) imageCache.get(f.getPath());

        if (bitmap == null) {

            bitmap = BitmapFactory.decodeFile(f.getPath());

            if (bitmap != null) {
                imageCache.put(f.getPath(), bitmap);
            }

        }
        // No? download it
        if (bitmap == null) {
            try {
                BitmapDownloaderTask task = new BitmapDownloaderTask(
                        imageView);
                DownloadedDrawable downloadedDrawable = new DownloadedDrawable(
                        task);
                imageView.setImageDrawable(downloadedDrawable);
                task.execute(url);
            } catch (Exception e) {
                Log.e("Error==>", e.toString());
            }

        } else {
            // Yes? set the image
            imageView.setImageBitmap(bitmap);
        }
    }
}

// cancel a download (internal only)
private static boolean cancelPotentialDownload(String url,
        ImageView imageView) {
    BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);

    if (bitmapDownloaderTask != null) {
        String bitmapUrl = bitmapDownloaderTask.url;
        if ((bitmapUrl == null) || (!bitmapUrl.equals(url))) {
            bitmapDownloaderTask.cancel(true);
        } else {
            // The same URL is already being downloaded.
            return false;
        }
    }
    return true;
}

// gets an existing download if one exists for the imageview
private static BitmapDownloaderTask getBitmapDownloaderTask(
        ImageView imageView) {
    if (imageView != null) {
        Drawable drawable = imageView.getDrawable();
        if (drawable instanceof DownloadedDrawable) {
            DownloadedDrawable downloadedDrawable = (DownloadedDrawable) drawable;
            return downloadedDrawable.getBitmapDownloaderTask();
        }
    }
    return null;
}

// our caching functions
// Find the dir to save cached images
private static File getCacheDirectory(Context context) {
    String sdState = android.os.Environment.getExternalStorageState();
    File cacheDir;

    if (sdState.equals(android.os.Environment.MEDIA_MOUNTED)) {
        File sdDir = android.os.Environment.getExternalStorageDirectory();

        // TODO : Change your diretcory here
        cacheDir = new File(sdDir, "data/ToDo/images");
    } else
        cacheDir = context.getCacheDir();

    if (!cacheDir.exists())
        cacheDir.mkdirs();
    return cacheDir;
}

private void writeFile(Bitmap bmp, File f) {
    FileOutputStream out = null;

    try {
        out = new FileOutputStream(f);
        bmp.compress(Bitmap.CompressFormat.PNG, 80, out);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (out != null)
                out.close();
        } catch (Exception ex) {
        }
    }
}

// download asynctask
public class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {
    private String url;
    private final WeakReference<ImageView> imageViewReference;

    public BitmapDownloaderTask(ImageView imageView) {
        imageViewReference = new WeakReference<ImageView>(imageView);
    }

    @Override
    // Actual download method, run in the task thread
    protected Bitmap doInBackground(String... params) {
        // params comes from the execute() call: params[0] is the url.
        url = (String) params[0];
        return downloadBitmap(params[0]);
    }

    @Override
    // Once the image is downloaded, associates it to the imageView
    protected void onPostExecute(Bitmap bitmap) {
        if (isCancelled()) {
            bitmap = null;
        }

        if (imageViewReference != null) {
            ImageView imageView = imageViewReference.get();
            BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);
            // Change bitmap only if this process is still associated with
            // it
            if (this == bitmapDownloaderTask) {
                imageView.setImageBitmap(bitmap);

                // cache the image

                String filename = String.valueOf(url.hashCode());
                File f = new File(
                        getCacheDirectory(imageView.getContext()), filename);

                imageCache.put(f.getPath(), bitmap);

                writeFile(bitmap, f);
            }
        }
    }

}

static class DownloadedDrawable extends ColorDrawable {
    private final WeakReference<BitmapDownloaderTask> bitmapDownloaderTaskReference;

    public DownloadedDrawable(BitmapDownloaderTask bitmapDownloaderTask) {
        super(Color.WHITE);
        bitmapDownloaderTaskReference = new WeakReference<BitmapDownloaderTask>(
                bitmapDownloaderTask);
    }

    public BitmapDownloaderTask getBitmapDownloaderTask() {
        return bitmapDownloaderTaskReference.get();
    }
}

// the actual download code
static Bitmap downloadBitmap(String url) {
    HttpParams params = new BasicHttpParams();
    params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION,
            HttpVersion.HTTP_1_1);
    HttpClient client = new DefaultHttpClient(params);
    final HttpGet getRequest = new HttpGet(url);

    try {
        HttpResponse response = client.execute(getRequest);
        final int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode != HttpStatus.SC_OK) {
            Log.w("ImageDownloader", "Error " + statusCode
                    + " while retrieving bitmap from " + url);
            return null;
        }

        final HttpEntity entity = response.getEntity();
        if (entity != null) {
            InputStream inputStream = null;
            try {
                inputStream = entity.getContent();
                final Bitmap bitmap = BitmapFactory
                        .decodeStream(inputStream);
                return bitmap;
            } finally {
                if (inputStream != null) {
                    inputStream.close();
                }
                entity.consumeContent();
            }
        }
    } catch (Exception e) {
        // Could provide a more explicit error message for IOException or
        // IllegalStateException
        getRequest.abort();
        Log.w("ImageDownloader", "Error while retrieving bitmap from "
                + url + e.toString());
    } finally {
        if (client != null) {
            // client.close();
        }
    }
    return null;
 }
}
 4
Author: Nikhil Gupta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-21 12:21:40

Miałem ten problem i zaimplementowałem lruCache. Wierzę, że potrzebujesz API 12 i wyżej lub użyj biblioteki compatiblity v4. lurCache to szybka pamięć, ale ma również budżet, więc jeśli martwisz się o to, możesz użyć diskcache... Wszystko opisane jest w buforowanie Bitmap.

Przedstawię teraz moją implementację, która jest singletonem wołam z dowolnego miejsca tak:

//Where the first is a string and the other is a imageview to load.

DownloadImageTask.getInstance().loadBitmap(avatarURL, iv_avatar);

Oto idealny kod do buforowania, a następnie wywołania powyższego w getView adaptera przy pobieraniu obrazu www:

public class DownloadImageTask {

    private LruCache<String, Bitmap> mMemoryCache;

    /* Create a singleton class to call this from multiple classes */

    private static DownloadImageTask instance = null;

    public static DownloadImageTask getInstance() {
        if (instance == null) {
            instance = new DownloadImageTask();
        }
        return instance;
    }

    //Lock the constructor from public instances
    private DownloadImageTask() {

        // Get max available VM memory, exceeding this amount will throw an
        // OutOfMemory exception. Stored in kilobytes as LruCache takes an
        // int in its constructor.
        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);

        // Use 1/8th of the available memory for this memory cache.
        final int cacheSize = maxMemory / 8;

        mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                // The cache size will be measured in kilobytes rather than
                // number of items.
                return bitmap.getByteCount() / 1024;
            }
        };
    }

    public void loadBitmap(String avatarURL, ImageView imageView) {
        final String imageKey = String.valueOf(avatarURL);

        final Bitmap bitmap = getBitmapFromMemCache(imageKey);
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap);
        } else {
            imageView.setImageResource(R.drawable.ic_launcher);

            new DownloadImageTaskViaWeb(imageView).execute(avatarURL);
        }
    }

    private void addBitmapToMemoryCache(String key, Bitmap bitmap) {
        if (getBitmapFromMemCache(key) == null) {
            mMemoryCache.put(key, bitmap);
        }
    }

    private Bitmap getBitmapFromMemCache(String key) {
        return mMemoryCache.get(key);
    }

    /* A background process that opens a http stream and decodes a web image. */

    class DownloadImageTaskViaWeb extends AsyncTask<String, Void, Bitmap> {
        ImageView bmImage;

        public DownloadImageTaskViaWeb(ImageView bmImage) {
            this.bmImage = bmImage;
        }

        protected Bitmap doInBackground(String... urls) {

            String urldisplay = urls[0];
            Bitmap mIcon = null;
            try {
                InputStream in = new java.net.URL(urldisplay).openStream();
                mIcon = BitmapFactory.decodeStream(in);

            } 
            catch (Exception e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }

            addBitmapToMemoryCache(String.valueOf(urldisplay), mIcon);

            return mIcon;
        }

        /* After decoding we update the view on the main UI. */
        protected void onPostExecute(Bitmap result) {
            bmImage.setImageBitmap(result);
        }
    }
}
 4
Author: j2emanue,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-16 13:34:56