it-swarm.com.de

Verspätetes Laden von Bildern in ListView

Ich verwende ein ListView, um einige mit diesen Bildern verknüpfte Bilder und Untertitel anzuzeigen. Ich bekomme die Bilder aus dem Internet. Gibt es eine Möglichkeit, die Bilder faul zu laden, sodass die Benutzeroberfläche nicht gesperrt ist, während der Text angezeigt wird, und Bilder beim Herunterladen angezeigt werden?

Die Gesamtzahl der Bilder ist nicht festgelegt.

1864
lostInTransit

Hier ist, was ich erstellt habe, um die Bilder zu halten, die meine App derzeit anzeigt. Beachten Sie, dass das hier verwendete "Log" -Objekt mein benutzerdefinierter Wrapper für die letzte Log-Klasse in Android ist.

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();
    }
}
1063
James A Wilson

Ich habe eine einfache Demo einer Lazy List (befindet sich bei GitHub) mit Bildern gemacht.

Grundsätzliche Verwendung

ImageLoader imageLoader=new ImageLoader(context); ...
imageLoader.DisplayImage(url, imageView); 

Vergessen Sie nicht, Ihrem AndroidManifest.xml die folgenden Berechtigungen hinzuzufügen:

 <uses-permission Android:name="Android.permission.INTERNET"/>
 <uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE"/> Please

erstellen Sie nur eine Instanz von ImageLoader und verwenden Sie sie in Ihrer gesamten Anwendung wieder. Auf diese Weise wird das Caching von Bildern wesentlich effizienter.

Es kann für jemanden hilfreich sein. Es werden Bilder im Hintergrund-Thread heruntergeladen. Bilder werden auf einer SD-Karte und im Speicher zwischengespeichert. Die Cache-Implementierung ist sehr einfach und reicht gerade für die Demo. Ich decodiere Bilder mit inSampleSize, um den Speicherverbrauch zu reduzieren. Ich versuche auch, recycelte Ansichten richtig zu behandeln.

Alt text

1015
Fedor

Ich empfehle Open Source Instrument niversal Image Loader. Es basiert ursprünglich auf Fedor Vlasovs Projekt LazyList und wurde seitdem erheblich verbessert.

  • Laden von Multithread-Bildern
  • Möglichkeit der umfassenden Optimierung der ImageLoader-Konfiguration (Thread-Ausführer, Downlaoder, Decoder, Speicher- und Disc-Cache, Anzeige von Image-Optionen und andere)
  • Möglichkeit des Zwischenspeicherns von Bildern im Speicher und/oder im Dateisystem des Geräts (oder auf der SD-Karte)
  • Möglichkeit zum "Abhören" des Ladevorgangs
  • Möglichkeit, jeden Anzeigebildaufruf mit getrennten Optionen anzupassen
  • Widget-Unterstützung
  • Android 2.0+ Unterstützung

548
nostra13

Multithreading For Performance , ein Tutorial von Gilles Debunne.

Dies stammt aus dem Entwickler-Blog von Android. Der vorgeschlagene Code verwendet:

  • AsyncTasks.
  • Eine harte, begrenzte Größe, FIFO cache.
  • Ein weicher, leicht garbage collect-fähiger Cache.
  • Ein Platzhalter Drawable während des Downloads.

enter image description here

155
Thomas Ahle

Update: Beachten Sie, dass diese Antwort jetzt ziemlich ineffektiv ist. Der Garbage Collector reagiert aggressiv auf SoftReference und WeakReference, sodass dieser Code NICHT für neue Apps geeignet ist. (Versuchen Sie stattdessen Bibliotheken wie niversal Image Loader , die in anderen Antworten vorgeschlagen werden. )

Vielen Dank an James für den Code und an Bao-Long für den Vorschlag, SoftReference zu verwenden. Ich habe die SoftReference-Änderungen in James 'Code implementiert. Leider hat SoftReferences dazu geführt, dass meine Bilder zu schnell über den Müll gesammelt wurden. In meinem Fall war es ohne das SoftReference-Zeug in Ordnung, weil meine Listengröße begrenzt ist und meine Bilder klein sind.

Es gibt eine Diskussion über die SoftReferences in Google Groups vor einem Jahr: Link zum Thread . Als Lösung für die zu frühe Garbage Collection schlagen sie die Möglichkeit vor, die VM -Heap-Größe mithilfe von dalvik.system.VMRuntime.setMinimumHeapSize () manuell festzulegen, was für mich nicht sehr attraktiv ist.

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

Picasso

Verwenden Sie die Picasso-Bibliothek von Jake Wharton. (Eine perfekte ImageLoading-Bibliothek vom Entwickler von ActionBarSherlock)

Eine leistungsstarke Bibliothek zum Herunterladen und Zwischenspeichern von Bildern für Android.

Bilder verleihen Android Anwendungen den dringend benötigten Kontext und das visuelle Flair. Picasso ermöglicht das problemlose Laden von Bildern in Ihre Anwendung - häufig in einer Codezeile!

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

Viele häufige Fehler beim Laden von Bildern auf Android werden von Picasso automatisch behoben:

Recycling von ImageView und Abbrechen des Downloads in einem Adapter. Komplexe Bildtransformationen mit minimalem Speicherbedarf. Automatisches Zwischenspeichern von Speicher und Festplatten.

Picasso Jake Whartons Bibliothek

Glide

Glide ist ein schnelles und effizientes Open-Source-Medienverwaltungsframework für Android, das die Dekodierung von Medien, das Speichern und Zwischenspeichern von Datenträgern sowie das Zusammenfassen von Ressourcen in einer einfachen und benutzerfreundlichen Oberfläche zusammenfasst.

Glide unterstützt das Abrufen, Dekodieren und Anzeigen von Videostandbildern, Bildern und animierten GIFs. Glide enthält eine flexible API, mit der Entwickler nahezu jeden Netzwerkstack anschließen können. Standardmäßig verwendet Glide einen benutzerdefinierten HttpUrlConnection-basierten Stapel, enthält jedoch auch Hilfsprogrammbibliotheken, die in Googles Volley-Projekt oder in die OkHttp-Bibliothek von Square eingebunden sind.

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

Der Hauptfokus von Glide liegt darauf, das Scrollen einer beliebigen Liste von Bildern so reibungslos und schnell wie möglich zu gestalten. Glide ist jedoch auch in fast allen Fällen wirksam, in denen Sie ein Remote-Bild abrufen, dessen Größe ändern und anzeigen müssen.

Glide Image Loading Library

Fresko von Facebook

Fresco ist ein leistungsstarkes System zum Anzeigen von Bildern in Android Anwendungen.

Fresco kümmert sich um das Laden und Anzeigen der Bilder, sodass Sie dies nicht tun müssen. Es lädt Bilder aus dem Netzwerk, aus dem lokalen Speicher oder aus lokalen Ressourcen und zeigt einen Platzhalter an, bis das Bild eingetroffen ist. Es hat zwei Cache-Ebenen; eines im Speicher und eines im internen Speicher.

Fresco Github

In Android 4.x und niedriger legt Fresco Bilder in einem speziellen Bereich des Android Speichers ab. Auf diese Weise wird Ihre Anwendung schneller ausgeführt und der gefürchtete OutOfMemoryError tritt viel seltener auf.

Fresko-Dokumentation

94
Ashwin S Ashok

Hochleistungslader - nachdem ich die hier vorgeschlagenen Methoden untersucht hatte, verwendete ich Bens Lösung mit einigen Änderungen -

  1. Mir ist klar geworden, dass die Arbeit mit Drawables schneller ist als mit Bitmaps, also verwende ich stattdessen Drawables

  2. Die Verwendung von SoftReference ist großartig, führt jedoch dazu, dass das zwischengespeicherte Bild zu oft gelöscht wird. Daher habe ich eine verknüpfte Liste mit Bildreferenzen hinzugefügt, die verhindert, dass das zu löschende Bild eine vordefinierte Größe erreicht

  3. Zum Öffnen des InputStreams habe ich Java.net.URLConnection verwendet, mit dem ich den Webcache verwenden kann (Sie müssen zuerst einen Antwortcache einrichten, aber das ist eine andere Geschichte).

Mein Code:

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;
}
}
81
Asaf Pinhassi

Ich habe dieses Android Training absolviert und ich denke, es leistet hervorragende Arbeit beim Herunterladen von Bildern, ohne die Hauptbenutzeroberfläche zu blockieren. Es behandelt auch das Zwischenspeichern und das Scrollen durch viele Bilder: Effizientes Laden großer Bitmaps

77
toobsco42

1. Picasso sorgt für Ärger Kostenloses Laden von Bildern in Ihre Anwendung - häufig in einer Codezeile!

Gradle verwenden:

implementation 'com.squareup.picasso:picasso:2.71828'

Nur eine Codezeile!

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

2. Glide Ein Bild laden und Caching-Bibliothek für Android mit Fokus auf flüssigem Scrollen

Gradle verwenden:

repositories {
  mavenCentral() 
  google()
}

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

// Für eine einfache Ansicht:

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

3. fresco ist ein mächtiges System zum Anzeigen von Bildern in Android Anwendungen. Fresco übernimmt das Laden und Anzeigen von Bildern, sodass Sie dies nicht tun müssen.

Erste Schritte mit Fresco

63
chiragkyada

Ich habe ein Tutorial geschrieben, das erklärt, wie man Bilder in einer Listenansicht faul lädt. Ich gehe im Detail auf die Themen Recycling und Nebenläufigkeit ein. Ich verwende auch einen festen Thread-Pool, um das Laichen vieler Threads zu verhindern.

Verspätetes Laden von Bildern im Listview Tutorial

51
Ben Ruijl

Das mache ich, indem ich einen Thread starte, um die Bilder im Hintergrund herunterzuladen und einen Rückruf für jedes Listenelement zu übergeben. Wenn ein Bild vollständig heruntergeladen wurde, wird der Rückruf aufgerufen, mit dem die Ansicht für das Listenelement aktualisiert wird.

Diese Methode funktioniert jedoch nicht sehr gut, wenn Sie Ansichten recyceln.

40
jasonhudgins

Ich möchte nur noch ein gutes Beispiel hinzufügen, XML-Adapter. Da es von Google verwendet wird und ich die gleiche Logik verwende, um einen OutOfMemory-Fehler zu vermeiden.

Grundsätzlich dieser ImageDownloader ist Ihre Antwort (da er die meisten Ihrer Anforderungen abdeckt). Einige können Sie auch darin implementieren.

31
Arslan Anwar

Ich habe NetworkImageView aus der neuen Android Volley Library com.Android.volley.toolbox.NetworkImageView verwendet und es scheint ziemlich gut zu funktionieren. Anscheinend ist dies die gleiche Ansicht, die in Google Play und anderen neuen Google-Anwendungen verwendet wird. Auf jeden Fall einen Besuch wert.

28
droidment

Dies ist ein häufiges Problem bei Android, das von vielen Leuten auf viele Arten gelöst wurde. Meiner Meinung nach ist die beste Lösung, die ich gesehen habe, die relativ neue Bibliothek Picasso . Hier sind die Highlights:

  • Open Source, aber geleitet von Jake Wharton von ActionBarSherlock Ruhm.
  • Laden Sie Bilder asynchron aus Netzwerk- oder App-Ressourcen mit einer Codezeile
  • Automatische ListView Erkennung
  • Automatisches Zwischenspeichern von Festplatten und Speicher
  • Kann benutzerdefinierte Transformationen durchführen
  • Viele konfigurierbare Optionen
  • Super einfache API
  • Häufig aktualisiert
27
howettl

Für das Laden von Bildern aus dem Internet gibt es viele Lösungen. Sie können auch die Bibliothek Android-Query verwenden. Es gibt Ihnen alle erforderlichen Aktivitäten. Stellen Sie sicher, was Sie tun möchten, und lesen Sie die Wiki-Seite der Bibliothek. Und lösen Sie die Einschränkung beim Laden von Bildern.

Das ist mein Code:

@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;
}

Es sollte Ihr fauler Ladevorgang lösen.

25
Rahul Rawat

Ich denke, dieses Problem ist bei Android Entwicklern sehr beliebt, und es gibt viele solcher Bibliotheken, die behaupten, dieses Problem zu beheben, aber nur einige von ihnen scheinen auf dem richtigen Weg zu sein. AQuery ist eine solche Bibliothek, aber in jeder Hinsicht besser als die meisten anderen und es lohnt sich, danach zu suchen.

24

Sie müssen versuchen, diesen Universal Loader ist am besten. Ich benutze dies nachdem ich viele RnD beim Lazy Loading gemacht habe.

niversal Image Loader

Funktionen

  • Laden von Multithread-Bildern (asynchron oder synchron)
  • Umfassende Anpassung der ImageLoader-Konfiguration (Thread-Ausführer, Downloader, Decoder, Speicher und Festplatten-Cache, Anzeige von Image-Optionen usw.)
  • Viele Anpassungsoptionen für jeden Aufruf von Anzeigebildern (Stub-Bilder, Caching-Schalter, Dekodierungsoptionen, Bitmap-Verarbeitung und -Anzeige usw.)
  • Bild-Caching im Speicher und/oder auf der Festplatte (Dateisystem des Geräts oder SD-Karte)
  • Ladevorgang abhören (einschließlich Ladevorgang)

Android 2.0+ Unterstützung

enter image description here

21
Girish Patel

Schauen Sie sich Shutterbug an, Applidiums leichter SDWebImage-Port (eine nette Bibliothek für iOS) für Android. Es unterstützt das asynchrone Caching, speichert fehlerhafte URLs, verarbeitet Parallelität gut und enthält hilfreiche Unterklassen.

Pull Requests (und Bug Reports) sind ebenfalls willkommen!

20
PatrickNLT

DroidParts hat ImageFetcher , für dessen Start keine Konfiguration erforderlich ist.

  • Verwendet eine Festplatte & im Speicher zuletzt verwendet (LRU) Cache.
  • Dekodiert effizient Bilder.
  • Unterstützt das Ändern von Bitmaps im Hintergrundthread.
  • Hat einfache Überblendung.
  • Hat einen Rückruf zum Ladevorgang des Bildes.

Clone DroidPartsGram für ein Beispiel:

Enter image description here

16
yanchenko

Nur ein kurzer Tipp für jemanden, der sich nicht sicher ist, welche Bibliothek für das verzögerte Laden von Bildern verwendet werden soll:

Es gibt vier grundlegende Möglichkeiten.

  1. Heimwerken => Nicht die beste Lösung, aber für ein paar Bilder und wenn Sie auf den Aufwand verzichten möchten, andere Bibliotheken zu verwenden

  2. Volley's Lazy Lädt Bibliothek => Von Jungs bei Android. Es ist schön und alles, aber schlecht dokumentiert und daher ein Problem zu verwenden.

  3. Picasso: Eine einfache Lösung, die einfach funktioniert. Sie können sogar die exakte Bildgröße angeben, die Sie einspielen möchten. Sie ist sehr einfach zu verwenden, für Apps, die mit einer enormen Menge an Bildern zu tun haben, jedoch möglicherweise nicht sehr "performant".

  4. UIL: Der beste Weg, um Bilder zu laden. Sie können Bilder zwischenspeichern (Sie benötigen natürlich eine Erlaubnis), den Loader einmal initialisieren und dann Ihre Arbeit erledigen. Die ausgereifteste Bibliothek zum asynchronen Laden von Bildern, die ich bisher gesehen habe.

16
Bijay Koirala

Novoda hat auch eine große Lazy Image Loading Library und viele Apps wie Songkick, Podio, SecretDJ und ImageSearch verwenden ihre Bibliothek.

Ihre Bibliothek wird hier auf Github gehostet und sie haben auch einen ziemlich aktiven Issues Tracker . Ihr Projekt scheint auch ziemlich aktiv zu sein, mit mehr als 300 Verpflichtungen zum Zeitpunkt des Schreibens dieser Antwort.

15
Soham

Überprüfen Sie meine Gabel von LazyList . Grundsätzlich verbessere ich die LazyList, indem ich den Aufruf der ImageView verzögere und zwei Methoden erstelle:

  1. Wenn Sie etwas wie "Bild wird geladen ..." einfügen müssen
  2. Wenn Sie das heruntergeladene Bild anzeigen müssen.

Ich habe auch den ImageLoader verbessert, indem ich ein Singleton in dieses Objekt implementiert habe.

13
Nicolas Jafelle

Alle obigen Codes haben ihren eigenen Wert, aber mit meiner persönlichen Erfahrung versuchen Sie es einfach mit Picasso.

Picasso ist eine Bibliothek speziell für diesen Zweck. Es verwaltet den Cache und alle anderen Netzwerkoperationen automatisch. Sie müssen die Bibliothek in Ihrem Projekt hinzufügen und schreiben Sie einfach eine einzelne Codezeile, um das Bild von der entfernten URL zu laden.

Bitte besuchen Sie hier: http://code.tutsplus.com/tutorials/Android-sdk-working-with-picasso--cms-22149

11
Akbar

Wenn Sie das Shimmer-Layout wie Facebook anzeigen möchten, gibt es dafür eine offizielle Facebook-Bibliothek. FaceBook Shimmer Android

Es kümmert sich um alles, Sie müssen nur Ihren gewünschten Design-Code verschachtelt in einen schimmernden Rahmen einfügen. Hier ist ein Beispielcode.

<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>

Und hier ist der Java Code dafür.

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

Fügen Sie diese Abhängigkeit in Ihre gradle-Datei ein.

implementation 'com.facebook.shimmer:shimmer:[email protected]'

So sieht es aus . Shimmer Android screenshot

11
Zankrut Parmar

Verwenden Sie die Glide-Bibliothek. Es hat für mich funktioniert und wird auch für Ihren Code funktionieren. Es funktioniert sowohl für Bilder als auch für Gifs.

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);
}
9
Saket Kumar

Geben Sie Aquery einen Versuch. Es hat erstaunlich einfache Methoden, um Bilder asynchron zu laden und zwischenzuspeichern.

7
user2779311

Ich kann einen anderen Weg empfehlen, der wie ein Zauber funktioniert: Android Query.

Sie können diese JAR -Datei von hier herunterladen

AQuery androidAQuery = new AQuery(this);

Als Beispiel:

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

Es ist sehr schnell und genau, und mit dieser Funktion finden Sie viele weitere Funktionen wie Animation beim Laden, Abrufen einer Bitmap (falls erforderlich) usw.

7
Pratik Dasa

RLImageViewHelper ist eine erstaunliche Bibliothek, die Ihnen dabei hilft.

7
DiegoAlt
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
Nikhil Gupta

Eine andere Möglichkeit besteht darin, über Ihren Adapter in einem Thread in Ihrer getView () -Methode Folgendes auszuführen:

Thread pics_thread = new Thread(new Runnable() {
    @Override
    public void run() {
        Bitmap bitmap = getPicture(url);
        if(bitmap != null) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    holder.imageview.setImageBitmap(bitmap);            
                    adapter.notifyDataSetChanged();
                }                       
            });             
        }       
    }                       
});

pics_thread.start();

natürlich sollten Sie Ihre Bilder immer zwischenspeichern, um zusätzliche Vorgänge zu vermeiden. Sie können Ihre Bilder in ein HashMap-Array einfügen, prüfen, ob das Bild im Array vorhanden ist. Wenn nicht, fahren Sie mit dem Thread fort, oder laden Sie das Bild aus Ihrem HashMap-Array. Stellen Sie außerdem immer sicher, dass Sie keinen Speicherleck haben. Bitmaps und Drawables sind häufig sehr speicherintensiv. Es liegt an Ihnen, Ihren Code zu optimieren.

4
Samet

Ich hatte dieses Problem und implementierte lruCache. Ich glaube, Sie benötigen API 12 und höher oder verwenden die Kompatibilitätsbibliothek v4. lurCache ist schnelles Gedächtnis, hat aber auch ein Budget. Wenn Sie sich also Sorgen machen, dass Sie einen Diskcache verwenden können ... Alles wird in Caching Bitmaps beschrieben .

Ich werde jetzt meine Implementierung bereitstellen, die ein Singleton ist. Ich rufe von überall so auf:

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

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

Hier ist der ideale Code zum Zwischenspeichern und anschließenden Aufrufen des obigen Befehls in getView eines Adapters, wenn das Web-Image abgerufen wird:

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
j2emanue

Sie können versuchen, die Aquery Android Bibliothek für Lazy Loading Bild und Listenansicht ... Der folgende Code kann Hilfe ..... Bibliothek hier herunterladen .

AQuery aq = new AQuery(mContext);
aq.id(R.id.image1).image("http://data.whicdn.com/images/63995806/original.jpg");
4
Chirag Ghori

verwenden Sie die untere Klasse, um Bilder in der Listenansicht herunterzuladen und zu laden. Sie speichert alle Bilder nach dem Herunterladen zwischen. Lädt auch Bilder und verzögert das Laden.

package com.fudiyoxpress.images;

import Java.io.File;
import Java.io.FileInputStream;
import Java.io.FileNotFoundException;
import Java.io.FileOutputStream;
import Java.io.IOException;
import Java.io.InputStream;
import Java.io.OutputStream;
import Java.net.HttpURLConnection;
import Java.net.URL;
import Java.util.Collections;
import Java.util.Map;
import Java.util.WeakHashMap;
import Java.util.concurrent.ExecutorService;
import Java.util.concurrent.Executors;

import Android.content.Context;
import Android.graphics.Bitmap;
import Android.graphics.BitmapFactory;
import Android.os.Handler;
import Android.widget.ImageView;

import com.fudiyoxpress.R;
import com.fudiyoxpress.config.Config;
import com.fudiyoxpress.Twitter.ScaleBitmap;

public class ImageLoader {

    // Initialize MemoryCache
    MemoryCache memoryCache = new MemoryCache();

    FileCache fileCache;

    Context C;

    // Create Map (collection) to store image and image url in key value pair
    private Map<ImageView, String> imageViews = Collections
            .synchronizedMap(new WeakHashMap<ImageView, String>());
    ExecutorService executorService;

    // handler to display images in UI thread
    Handler handler = new Handler();

    public ImageLoader(Context context) {

        C = context;
        fileCache = new FileCache(context);

        // Creates a thread pool that reuses a fixed number of
        // threads operating off a shared unbounded queue.
        executorService = Executors.newFixedThreadPool(5);

    }

    // default image show in list (Before online image download)
    final int stub_id = R.drawable.restlogoplaceholder;

    public void DisplayImage(String url, ImageView imageView, Context context,
            boolean header_flag) {

        Bitmap largeIcon = BitmapFactory.decodeResource(context.getResources(),
                R.drawable.restlogoplaceholder);
        header_flag = false;
        // Store image and url in Map
        imageViews.put(imageView, url);

        // Check image is stored in MemoryCache Map or not (see
        // MemoryCache.Java)
        Bitmap bitmap = memoryCache.get(url);

        if (bitmap != null) {
            // if image is stored in MemoryCache Map then
            // Show image in listview row
            Bitmap b = ScaleBitmap
                    .getScaledBitmap(context, bitmap, header_flag);
            imageView.setImageBitmap(b);

        } else {
            // queue Photo to download from url
            queuePhoto(url, imageView, header_flag);

            // Before downloading image show default image
            imageView.setImageBitmap(ScaleBitmap.getScaledBitmap(context,
                    largeIcon, header_flag));

        }
    }



    private void queuePhoto(String url, ImageView imageView, boolean header_flag) {
        // Store image and url in PhotoToLoad object
        PhotoToLoad p = new PhotoToLoad(url, imageView, header_flag);

        // pass PhotoToLoad object to PhotosLoader runnable class
        // and submit PhotosLoader runnable to executers to run runnable
        // Submits a PhotosLoader runnable task for execution

        executorService.submit(new PhotosLoader(p));
    }

    // Task for the queue
    private class PhotoToLoad {
        public String url;
        public ImageView imageView;
        public boolean b;

        public PhotoToLoad(String u, ImageView i, boolean header_flag) {
            url = u;
            imageView = i;
            b = header_flag;
        }
    }

    class PhotosLoader implements Runnable {
        PhotoToLoad photoToLoad;

        PhotosLoader(PhotoToLoad photoToLoad) {
            this.photoToLoad = photoToLoad;
        }

        @Override
        public void run() {
            try {
                // Check if image already downloaded
                if (imageViewReused(photoToLoad))
                    return;
                // download image from web url
                Bitmap bmp = getBitmap(photoToLoad.url);

                // set image data in Memory Cache
                memoryCache.put(photoToLoad.url, bmp);

                if (imageViewReused(photoToLoad))
                    return;

                // Get bitmap to display
                BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad);

                // Causes the Runnable bd (BitmapDisplayer) to be added to the
                // message queue.
                // The runnable will be run on the thread to which this handler
                // is attached.
                // BitmapDisplayer run method will call
                handler.post(bd);

            } catch (Throwable th) {
                // th.printStackTrace();
            }
        }
    }

    private Bitmap getBitmap(String url) {
        File f = fileCache.getFile(url);

        // from SD cache
        // CHECK : if trying to decode file which not exist in cache return null
        Bitmap b = decodeFile(f);
        if (b != null)
            return b;

        // Download image file from web
        try {

            // // download the image
            Bitmap bitmap = null;

            URL imageURL = null;
            try {

                imageURL = new URL(Config.WEB_URL + "/ServeBlob?id=" + url);

                HttpURLConnection connection = (HttpURLConnection) imageURL
                        .openConnection();
                connection.setDoInput(true);
                connection.connect();
                // if(!(new File(imageURL.toString())).exists())
                // {
                // imageURL=new URL("");
                // }
                InputStream inputStream = connection.getInputStream();

                // Constructs a new FileOutputStream that writes to
                // file
                // if file not exist then it will create file
                OutputStream os = new FileOutputStream(f);

                // See Utils class CopyStream method
                // It will each pixel from input stream and
                // write pixels to output stream (file)
                Utils.CopyStream(inputStream, os);

                os.close();

                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = 8;

                bitmap = BitmapFactory.decodeStream(inputStream, null, options);

            } catch (IOException e) {

                // e.printStackTrace();
            }

            // Now file created and going to resize file with defined height
            // Decodes image and scales it to reduce memory consumption
            bitmap = decodeFile(f);

            return bitmap;

        } catch (Throwable ex) {
            ex.printStackTrace();
            if (ex instanceof OutOfMemoryError)
                memoryCache.clear();
            return null;
        }
    }

    // Decodes image and scales it to reduce memory consumption
    private Bitmap decodeFile(File f) {

        try {

            // Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            FileInputStream stream1 = new FileInputStream(f);
            BitmapFactory.decodeStream(stream1, null, o);
            stream1.close();

            // Find the correct scale value. It should be the power of 2.

            // Set width/height of recreated image
            final int REQUIRED_SIZE = 85;

            int width_tmp = o.outWidth, height_tmp = o.outHeight;
            int scale = 1;
            while (true) {
                if (width_tmp / 2 < REQUIRED_SIZE
                        || height_tmp / 2 < REQUIRED_SIZE)
                    break;
                width_tmp /= 2;
                height_tmp /= 2;
                scale *= 2;
            }

            // decode with current scale values
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            FileInputStream stream2 = new FileInputStream(f);
            Bitmap bitmap = BitmapFactory.decodeStream(stream2, null, o2);
            stream2.close();
            return bitmap;

        } catch (FileNotFoundException e) {
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    boolean imageViewReused(PhotoToLoad photoToLoad) {

        String tag = imageViews.get(photoToLoad.imageView);
        // Check url is already exist in imageViews MAP
        if (tag == null || !tag.equals(photoToLoad.url))
            return true;
        return false;
    }

    // Used to display bitmap in the UI thread
    class BitmapDisplayer implements Runnable {
        Bitmap bitmap;
        PhotoToLoad photoToLoad;

        public BitmapDisplayer(Bitmap b, PhotoToLoad p) {
            bitmap = b;
            photoToLoad = p;
        }

        public void run() {
            if (imageViewReused(photoToLoad))
                return;

            // Show bitmap on UI
            if (bitmap != null) {
                photoToLoad.imageView.setImageBitmap(ScaleBitmap
                        .getScaledBitmap(C, bitmap, photoToLoad.b));
            } else {

            }
            // photoToLoad.imageView.setImageResource(stub_id);

        }
    }

    public void clearCache() {
        // Clear cache directory downloaded images and stored data in maps
        memoryCache.clear();
        fileCache.clear();
    }

}




package com.fudiyoxpress.images;

import Java.util.Collections;
import Java.util.Iterator;
import Java.util.LinkedHashMap;
import Java.util.Map;
import Java.util.Map.Entry;
import Android.graphics.Bitmap;
import Android.util.Log;

public class MemoryCache {

    private static final String TAG = "MemoryCache";

    //Last argument true for LRU ordering
    private Map<String, Bitmap> cache = Collections.synchronizedMap(
            new LinkedHashMap<String, Bitmap>(10,1.5f,true));

   //current allocated size
    private long size=0; 

    //max memory cache folder used to download images in bytes
    private long limit = 1000000; 

    public MemoryCache(){

        //use 25% of available heap size
        setLimit(Runtime.getRuntime().maxMemory()/4);
    }

    public void setLimit(long new_limit){

        limit=new_limit;
        Log.i(TAG, "MemoryCache will use up to "+limit/1024./1024.+"MB");
    }

    public Bitmap get(String id){
        try{
            if(!cache.containsKey(id))
                return null;
            //NullPointerException sometimes happen here http://code.google.com/p/osmdroid/issues/detail?id=78 
            return cache.get(id);
        }catch(NullPointerException ex){
            ex.printStackTrace();
            return null;
        }
    }

    public void put(String id, Bitmap bitmap){
        try{
            if(cache.containsKey(id))
                size-=getSizeInBytes(cache.get(id));
            cache.put(id, bitmap);
            size+=getSizeInBytes(bitmap);
            checkSize();
        }catch(Throwable th){
            th.printStackTrace();
        }
    }

    private void checkSize() {
        Log.i(TAG, "cache size="+size+" length="+cache.size());
        if(size>limit){
            Iterator<Entry<String, Bitmap>> iter=cache.entrySet().iterator();//least recently accessed item will be the first one iterated  
            while(iter.hasNext()){
                Entry<String, Bitmap> entry=iter.next();
                size-=getSizeInBytes(entry.getValue());
                iter.remove();
                if(size<=limit)
                    break;
            }
            Log.i(TAG, "Clean cache. New size "+cache.size());
        }
    }

    public void clear() {
        try{
            //NullPointerException sometimes happen here http://code.google.com/p/osmdroid/issues/detail?id=78 
            cache.clear();
            size=0;
        }catch(NullPointerException ex){
            ex.printStackTrace();
        }
    }

    long getSizeInBytes(Bitmap bitmap) {
        if(bitmap==null)
            return 0;
        return bitmap.getRowBytes() * bitmap.getHeight();
    }
}




package com.fudiyoxpress.images;

import Java.io.InputStream;
import Java.io.OutputStream;

public class Utils {
    public static void CopyStream(InputStream is, OutputStream os)
    {
        final int buffer_size=1024;
        try
        {

            byte[] bytes=new byte[buffer_size];
            for(;;)
            {
              //Read byte from input stream

              int count=is.read(bytes, 0, buffer_size);
              if(count==-1)
                  break;

              //Write byte from output stream
              os.write(bytes, 0, count);
            }
        }
        catch(Exception ex){}
    }
}
3
Jotiram Chavan

Ich benutze droidQuery . Es gibt zwei Mechanismen zum Laden eines Bildes von einer URL. Die erste (Kurzform) ist einfach:

$.with(myView).image(url);

Dies kann sehr einfach in die getView(...) -Methode von ArrayAdapter eingefügt werden.


Die Longhand-Methode bietet viel mehr Steuerungsmöglichkeiten und verfügt über Optionen, die hier noch nicht einmal erläutert wurden (z. B. Cache und Rückrufe). Eine grundlegende Implementierung, die die Ausgabegröße auf 200 x 200 Pixel festlegt, finden Sie hier:

$.ajax(new AjaxOptions().url(url)
    .type("GET")
    .dataType("image")
    .imageWidth(200).imageHeight(200)
    .success(new Function() {
        @Override
        public void invoke($ droidQuery, Object... params) {
            myImageView.setImageBitmap((Bitmap) params[0]);
        }
    })
    .error(new Function() {
        @Override
        public void invoke($ droidQuery, Object... params) {
            AjaxError e = (AjaxError) params[0];
            Log.e("$", "Error " + e.status + ": " + e.error);
        }
    })
);
3
Phil

In einigen Antworten wurde bereits die Verwendung verschiedener Bildbibliotheken wie Universal Image Loader und androidimageloader usw. erwähnt. Dies ist eine alte Frage, aber für alle, die noch nach so etwas suchen, gibt es mehrere solcher Bibliotheken zum Laden/Zwischenspeichern von Bildern.

3
redGREENblue

Sie können eine Bibliothek von Drittanbietern wie Piccaso oder Volley für ein effektives verzögertes Laden verwenden. Sie können auch Ihre eigenen erstellen, indem Sie die folgenden Schritte ausführen

  1. Implementieren Sie Code zum Herunterladen des Bildes von der URL

  2. Implementieren eines Caching-Mechanismus zum Speichern und Abrufen von Bildern (Verwenden Sie LruCache von Android zum Caching)

2
BalaramNayak

Ich fand Glide als bessere Option als Picasso. Ich habe Picasso verwendet, um ungefähr 32 Bilder mit einer Größe von ungefähr 200-500KB zu laden, und ich habe immer OOM erhalten. Aber das Glide hat alle meine OOM Probleme gelöst.

2
Sanjeet A

Sie können AsyncImageView von GreenDroid verwenden. Rufen Sie einfach setUrl an, und ich denke, dies könnte Ihnen dabei helfen, das zu tun, was Sie nicht tun möchten, und verweisen Sie auf den unten angegebenen Link:

Link für die Asyncimage-Ansicht von greenDroid

0
Imran

Mit Ausnahme des asynchronen Ladens des Datencaches benötigen Sie möglicherweise den UI-Cache

Mit Ausnahme der sichtbaren Artikeldaten für das Laden müssen Sie möglicherweise die für die Annäherung sichtbaren Artikeldaten laden

Beispiel: Angenommen, das in der Listenansicht sichtbare Element ist [6,7,8,9,10]. Möglicherweise müssen Sie [6,7,8,9,10] laden UND das Element [1, 2, 3, 4] vorladen , 5] & [11, 12, 13, 14, 15], da der Benutzer wahrscheinlich zur Vor- oder Nachseite blättert

0
Yessy