Frage

Ich bin mit einem ListView einige Bilder und Beschriftungen mit den Bildern verknüpft angezeigt werden soll. Ich erhalte die Bilder aus dem Internet. Gibt es eine Möglichkeit zu faul Last die Bilder so, während die Textanzeigen wird die Benutzeroberfläche nicht gesperrt und Bilder angezeigt werden, wenn sie heruntergeladen werden?

Die Gesamtzahl der Bilder ist nicht festgelegt.

War es hilfreich?

Lösung

Hier ist, was ich geschaffen, um die Bilder zu halten, die meine app derzeit angezeigt wird. Bitte beachten Sie, dass die „Log“ Objekt im Einsatz hier meine benutzerdefinierte Wrapper um die letzte Log-Klasse innerhalb 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();
    }
}

Andere Tipps

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

  • Multi-Thread-Bild Laden
  • Möglichkeit der breiten Tuning Imageloader Konfiguration (Gewinde Testamentsvollstrecker, Downlaoder, Decoder, Speicher und Disk-Cache, Anzeigebildoptionen und andere)
  • Möglichkeit der Bild Caching im Speicher und / oder auf Gerätedatei sysytem (oder SD-Karte)
  • Möglichkeit zu "hören" Ladevorgang
  • Möglichkeit jedes Anzeigebild Anruf mit getrennten Optionen anpassen
  • Widget-Unterstützung
  • Android 2.0+ Unterstützung

Multithreading For Performance , ein Tutorial von Gilles Debunne.

Dies ist aus dem Android Developers Blog. Der vorgeschlagene Code verwendet:

  • AsyncTasks.
  • Eine harte, begrenzte Größe, FIFO cache.
  • Eine weiche, leicht garbage collect-ed-Cache.
  • A Platzhalter Drawable während Sie herunterladen.

eingeben Bild Beschreibung hier

Update: Beachten Sie, dass diese Antwort jetzt ziemlich ineffektiv ist. Der Garbage Collector wirkt aggressiv auf und Softreference WeakReference, sodass dieser Code ist nicht geeignet für neue Anwendungen. (Stattdessen versuchen Bibliotheken wie Universal-Image Loader in anderen Antworten vorgeschlagen.)

Dank James für den Code, und Bao-Long für den Vorschlag der Verwendung von Softreference. Ich setzte die Softreference Änderungen auf James' Code. Leider SoftReferences verursacht meine Bilder Müll gesammelt zu schnell sein. In meinem Fall war es ohne die Softreference Sachen in Ordnung, weil meine Liste Größe begrenzt ist und meine Bilder sind klein.

Es gibt eine Diskussion von vor einem Jahr in Bezug auf die SoftReferences auf Google Groups: Link fädeln . Als Lösung für die allzu früh Müllabfuhr, schlagen sie die Möglichkeit, manuell die VM-Heap-Größe Einstellung mit dalvik.system.VMRuntime.setMinimumHeapSize (), die mir 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();
}

Picasso

Mit Jake Wharton Picasso Bibliothek. (A Perfect ImageLoading Bibliothek die Entwickler von ActionBarSherlock bilden)

Ein starkes Bild Herunterladen und Caching-Bibliothek für Android.

Bilder hinzufügen dringend benötigten Kontext und visuelles Flair Android-Anwendungen. Picasso ermöglicht mühelosen Laden von Bildern in Ihren applikations oft in einer Zeile Code!

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

Viele häufige Fehler von Bild Laden auf Android werden automatisch von Picasso behandelt:

Handhabung Image Recycling und Download Stornierung in einem Adapter. Komplexe Bildtransformationen mit minimalem Speicherverbrauch. Automatische Speicher und Festplatten-Cache.

Picasso Jake Wharton Bibliothek

Glide

Glide ist eine schnelle und effiziente Open-Source-Media-Management-Framework für Android, die Medien-Decodierung Wraps, Speicher und Festplatten-Cache und Ressourcen in einer einfachen und leicht Pooling-Schnittstelle zu verwenden.

Glide unterstützt fetching, Dekodierung und Anzeige von Videostills, Bilder und animierte GIFs. Glide eine flexible api, die Entwickler zu stecken in fast jedem Netzwerk-Stack ermöglicht. Standardmäßig Glide verwendet eine benutzerdefinierte HttpURLConnection basierten Stapel, sondern auch Dienstprogramm Bibliotheken stecken in den Google-Volley-Projekt oder OkHttp Bibliothek Platz statt.

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

Glide Der primäre Fokus liegt auf dem jede Art von Liste der Bilder, so glatt und schnell wie möglich Scrollen, aber Glide ist auch für fast jeden Fall, wo Sie holen müssen, Größe ändern, und ein Remote-Bild angezeigt werden soll.

Glide Bild Laden Bibliothek

Fresko von Facebook

Fresco ist ein leistungsfähiges System für Bilder in Android-Anwendungen angezeigt werden.

Fresco nimmt Bild Laden und Anzeigen, so dass Sie nicht haben. Es werden die Bilder aus dem Netz, lokalen Speicher laden, oder lokale Ressourcen und einen Platzhalter angezeigt werden, bis das Bild angekommen ist. Es verfügt über zwei Cache-Ebene; einen Speicher und eine andere in internen Speicher.

Fresco Github

In Android 4.x und niedriger legt Fresco Bilder in einem speziellen Bereich des Android-Speichers. Auf diese Weise können Sie Ihre Anwendung schneller laufen -. Und leiden die gefürchtete OutOfMemoryError viel seltener

Fresco Dokumentation

Hochleistungslader - nach den Methoden, die hier vorgeschlagen untersuchen, Ich benutzte Bens Lösung mit einigen Änderungen -

  1. Ich erkannte, dass mit Drawables schneller arbeiten, ist, dass mit Bitmaps so ich Drawables verwendet stattdessen

  2. Mit Softreference ist groß, aber es macht das im Cache gespeicherten Bild zu oft gelöscht werden, so dass ich hinzugefügt Liste einer verknüpften die Bilder Referenzen hält, aus dem Bild zu verhindern gelöscht werden, bis sie eine vorgegebene Größe erreicht

  3. Um die Input öffne ich java.net.URLConnection verwendet, die mir Web-Cache verwenden können (Sie zuerst eine Antwort Cache festlegen müssen, 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;
}
}

Ich habe diese Android Ausbildung gefolgt und ich denke, es hat eine ausgezeichnete Arbeit bei Herunterladen von Bildern, ohne den Haupt-UI blockiert. Es behandelt auch Caching und den Umgang mit vielen Bildern Scrollen durch: Effizientes Große Bitmaps Laden

1. Picasso ermöglicht stressfreies Bild Laden in Ihren applikations oft in einer Zeile Code!

Verwendung Gradle:

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

Nur eine Zeile Code!

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

2. Glide Ein Bild Lade und Caching-Bibliothek für Android konzentrierten sich auf smooth scrolling

Verwendung Gradle:

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 leistungsfähiger System für Bilder in Android Anzeige    applications.Fresco kümmert sich um Bild Laden und Anzeigen, so dass Sie sich nicht   zu.

mit Fresko Getting Started

Ich habe ein Tutorial geschrieben, das erklärt, wie faul-Laden von Bildern in einer Listenansicht zu tun. Ich gehe in einige Details über die Fragen des Recyclings und die Gleichzeitigkeit. Ich habe auch einen festen Thread-Pool verwenden, um zu verhindern viele Fäden Laichen.

faulen Laden von Bildern in Listenansicht Tutorial

So wie ich es tue, ist durch einen Thread startet die Bilder im Hintergrund herunterladen und einen Rückruf für jedes Listenelement übergeben. Wenn ein Bild fertig ist das Herunterladen ruft sie den Rückruf, die den Blick für das Listenelement aktualisiert.

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

Ich will nur ein weiteres gutes Beispiel hinzuzufügen, XML-Adapter . Wie es wird von Google verwendet, und ich bin auch mit der gleichen Logik einen OutOfMemory Fehler zu vermeiden.

Im Grunde diese ImageDownloader ist Ihre Antwort ( wie es deckt die meisten Ihrer Anforderungen). Einige können Sie auch in der Umsetzung.

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

Dies ist ein häufiges Problem auf Android, die in vielerlei Hinsicht von vielen Menschen gelöst. Meiner Meinung nach ist die beste Lösung, die ich gesehen habe, die relativ neue Bibliothek namens Picassos . Hier sind die Highlights:

  • Open Source, aber unter Leitung von Jake Wharton von ActionBarSherlock Ruhm.
  • Asynchron laden Bilder aus dem Netzwerk oder App-Ressourcen mit einer Codezeile
  • Automatische Erkennung ListView
  • Automatische Festplatte und Speicher-Caching
  • Kann benutzerdefinierte Transformationen tun
  • Viele konfigurierbaren Optionen
  • Super einfache API
  • Häufig aktualisiert

Nun, Bildladezeit aus dem Internet hat viele Lösungen. Sie können auch die Bibliothek Android-Abfrage verwenden. Es wird Ihnen alle erforderlichen Aktivitäten. Achten Sie darauf, was Sie die Bibliothek Wiki-Seite tun und lesen möchten. Und löst die Bildladebeschränkung.

Dies 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 verzögertes Laden Problem lösen.

Ich denke, dieses Thema unter dem Android-Entwicklern sehr beliebt, und es gibt viele solche Bibliotheken, die dieses Problem zu beheben behauptet, aber nur wenige von ihnen scheinen auf der Marke zu sein. AQuery ist eine solche Bibliothek, aber es ist besser, als die meisten von ihnen in allen Aspekten und lohnt sich für den Versuch.

Sie müssen versuchen, diese Universal-Loader am besten ist. Ich verwende diese nach vielen RnD auf verzögertes Laden getan.

Universal-Image Loader

Funktionen

  • Multithread Bildlade (async oder sync)
  • Breite Anpassung von Imageloader Konfiguration (Thread Testamentsvollstrecker, Downloader, Decoder, Speicher und Festplatten-Cache, Anzeigebildoptionen, etc.)
  • Viele Anpassungsoptionen für jeden Anzeigebildaufruf (Stub Bilder, Caching-Schalter, Dekodieroptionen, Bitmap Verarbeitung und Anzeige, usw.)
  • Bild-Caching im Speicher und / oder auf der Festplatte (Gerätedateisystem oder SD-Karte)
  • Zuhören Ladevorgang (einschließlich Download Fortschritt)

Android 2.0+ Unterstützung

eingeben Bild Beschreibung hier

Hier finden Sie aktuelle Shutterbug , Applidium Leichtbau SDWebImage (eine schöne Bibliothek auf iOS) -Anschluss auf Android. Es unterstützt asynchrones Caching, speichert fehlgeschlagen URLs, Griffe Gleichzeitigkeit gut und nützlich Unterklassen enthalten sind.

Pull-Requests (und Fehlerberichte) sind willkommen, auch!

DroidParts hat ImageFetcher , die Null-Konfiguration erfordert, um loszulegen.

  • Verwendet eine Scheibe & In-Memory- Least Recently Used (LRU) Cache.
  • Effizientes dekodiert Bilder.
  • Unterstützung von Bitmaps in Hintergrund-Thread zu ändern.
  • Hat einfachen Cross-Fade.
  • Hat Bild Ladevorgang Rückruf.

DroidPartsGram für ein Beispiel:

Geben Sie Bildbeschreibung hier

Nur ein kurzer Tipp für jemanden, der in Unentschlossenheit ist in Bezug auf welcher Bibliothek für faul-Laden von Bildern zu verwenden:

Es gibt vier grundlegende Möglichkeiten.

  1. DIY => Nicht die beste Lösung, aber für ein paar Bilder, und wenn Sie ohne lästiges gehen wollen von anderen Bibliotheken

  2. Volley des Lazy Loading-Bibliothek => Von Jungs von Android. Es ist schön und alles ist aber schlecht dokumentiert und ist daher ein Problem zu verwenden.

  3. Picasso: Eine einfache Lösung, die nur funktioniert, können Sie auch die genaue Bildgröße geben Sie in bringen wollen Es ist sehr einfach zu bedienen, aber vielleicht nicht sehr „performant“ für Anwendungen, die zu bewältigen haben. gigantische Mengen von Bildern.

  4. UIL: Der beste Weg zu faul Last Bildern. Sie können Bilder Cache (Sie Erlaubnis natürlich müssen), wenn der Lader initialisieren, dann haben Sie Ihre Arbeit getan. Die reifste asynchrone Bildlade Bibliothek ich je bisher gesehen haben.

Novoda hat auch eine große faul Bild Laden Bibliothek und viele Anwendungen wie Songkick, Podio, SecretDJ und Imagesearch ihre Bibliothek verwenden.

Die Bibliothek wird gehostet hier auf Github und sie haben eine ziemlich aktiv Fragen tracker auch. Ihr Projekt scheint zu schön, aktiv zu sein, mit mehr als 300 + begeht zum Zeitpunkt des Schreibens dieser Antwort.

Überprüfen Sie meine Gabel von LazyList . Im Grunde habe ich die LazyList verbessern, indem sie den Ruf des Image verzögern und schaffen zwei Methoden:

  1. Wenn Sie brauchen so etwas wie setzen „Lade Bild ...“
  2. Wenn Sie das heruntergeladene Bild zeigen müssen.

Ich verbesserte auch die Imageloader durch eine Singletons in diesem Objekt.

Alle obigen Code ihren eigenen Wert haben, aber mit meiner persönlichen Erfahrung nur einen Versuch mit Picasso geben.

Picasso ist eine Bibliothek, die speziell für diesen Zweck in-der Tat wird es verwalten Cache und alle anderen Netzwerkoperationen automatically.You wird Bibliothek in einem Projekt hinzuzufügen haben und nur eine einzige Zeile Code schreiben Bild von Remote-URL zu laden.

Bitte besuchen Sie hier: http: // Code .tutsplus.com / tutorials / android-sdk-Arbeits-with-picasso - cms-22149

Wenn Sie Shimmer Layout wie Facebook anzeigen möchten gibt es eine offizielle Facebook-Bibliothek für die. Facebook Shimmer Android

Es kümmert sich um alles, Sie müssen nur Ihre gewünschte Design Code in verschachtelter Weise in Schimmer Rahmen setzen. 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 für sie.

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

Fügen Sie diese Abhängigkeit in Ihrer gradle Datei.

implementation 'com.facebook.shimmer:shimmer:0.1.0@aar'

Hier ist, wie es aussieht

Mit der glide Bibliothek. Er arbeitete für mich und wird für Ihren Code arbeiten too.It als auch für beide Bilder arbeitet als auch 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);
}

Ich kann eine andere Art und Weise empfehlen, wie ein Zauber funktioniert. Android Abfrage

können Sie das JAR Herunterladen Datei von hier

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 diese verwenden, können Sie viele weitere Funktionen wie Animation beim Laden, immer ein Bitmap (falls erforderlich), usw. finden.

Aquery einen Versuch. Es hat erstaunlich einfache Methoden zu laden und Cache-Bilder asynchron.

URLImageViewHelper ist eine erstaunliche Bibliothek, die Sie das tun können.

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

Ich hatte dieses Problem und umgesetzt LRUCache. Ich glaube, Sie API benötigen 12 und höher oder die Kompatiblität v4 Bibliothek verwenden. lurCache ist schneller Speicher, aber es hat auch ein Budget, so dass, wenn Sie besorgt sind, dass Sie eine diskcache verwenden können ... Es ist alles in beschrieben Caching Bitmaps .

Ich werde nun meine Implementierung zur Verfügung stellen, die eine Singletons ich von überall wie folgt aufrufen:

//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 zwischenzuspeichern und dann die oben in getView eines Adapters aufrufen, wenn die Web-Bild abrufen:

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);
        }
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top