web-dev-qa-db-fra.com

Chargement paresseux d'images dans ListView

J'utilise un ListView pour afficher certaines images et légendes associées à ces images. Je reçois les images d'Internet. Existe-t-il un moyen de charger paresseusement les images de sorte que, pendant l'affichage du texte, l'interface utilisateur n'est pas verrouillée et les images sont affichées au fur et à mesure qu'elles sont téléchargées?

Le nombre total d'images n'est pas fixé.

1864
lostInTransit

Voici ce que j'ai créé pour contenir les images que mon application affiche actuellement. Veuillez noter que l'objet "Journal" utilisé ici est mon wrapper personnalisé pour la classe de journalisation finale dans Android.

package com.wilson.Android.library;

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

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

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

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

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

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

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


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

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

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

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

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

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

J'ai fait ne simple démonstration d'une liste paresseuse (située sur GitHub) avec des images.

Utilisation de base

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

N'oubliez pas d'ajouter les autorisations suivantes à votre fichier AndroidManifest.xml:

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

créez une seule instance d'ImageLoader et réutilisez-la dans votre application. De cette façon, la mise en cache des images sera beaucoup plus efficace.

Cela peut être utile à quelqu'un. Il télécharge des images dans le fil de fond. Les images sont mises en cache sur une carte SD et en mémoire. L'implémentation du cache est très simple et suffit pour la démo. Je décode des images avec inSampleSize pour réduire la consommation de mémoire. J'essaie également de gérer correctement les vues recyclées.

Alt text

1015
Fedor

Je recommande un instrument open source niversal Image Loader. Il est à l'origine basé sur le projet de Fedor Vlasov LazyList et a été grandement amélioré depuis.

  • Chargement d'image multithread
  • Possibilité de réglage étendu de la configuration d'ImageLoader (exécuteurs de threads, downlaoder, décodeur, mémoire et cache de disque, options d'image d'affichage et autres)
  • Possibilité de mise en cache des images en mémoire et/ou sur le système de fichiers (ou la carte SD) de l'appareil
  • Possibilité de "écouter" le processus de chargement
  • Possibilité de personnaliser chaque appel d'image d'affichage avec des options séparées
  • Support de widget
  • Prise en charge d'Android 2.0+

548
nostra13

Multithreading For Performance , tutoriel de Gilles Debunne.

Cela provient du Android Blog des développeurs. Le code suggéré utilise:

  • AsyncTasks.
  • Une taille dure et limitée, FIFO cache.
  • Cache souple garbage collect- facilement.
  • Un espace réservé Drawable pendant le téléchargement.

enter image description here

155
Thomas Ahle

Mise à jour: Notez que cette réponse est plutôt inefficace pour le moment. Le ramasse-miettes agit de manière agressive sur SoftReference et WeakReference, de sorte que ce code n'est PAS adapté aux nouvelles applications. (Au lieu de cela, essayez des bibliothèques comme niversal Image Loader suggérées dans d'autres réponses. )

Merci à James pour le code et à Bao-Long pour la suggestion d'utiliser SoftReference. J'ai implémenté les modifications de SoftReference sur le code de James. Malheureusement, SoftReferences a entraîné le ramassage trop rapide de mes images. Dans mon cas, tout se passait bien sans SoftReference, car la taille de ma liste est limitée et mes images sont petites.

Il y a une discussion d'il y a un an concernant les SoftReferences sur les groupes de Google: lien vers le fil . En guise de solution à la récupération de place trop précoce, ils suggèrent la possibilité de définir manuellement la taille de segment VM à l'aide de dalvik.system.VMRuntime.setMinimumHeapSize (), ce qui ne m'intéresse pas beaucoup.

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

Utilisez la bibliothèque Picasso de Jake Wharton. (Une bibliothèque Perfect ImageLoading constitue le développeur d’ActionBarSherlock)

Une puissante bibliothèque de téléchargement et de mise en cache d'images pour Android.

Les images ajoutent un contexte et une touche visuelle indispensables aux applications Android. Picasso permet de charger des images sans problème dans votre application, souvent en une seule ligne de code!

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

De nombreux pièges courants liés au chargement d'images sur Android sont gérés automatiquement par Picasso:

Gestion du recyclage d'ImageView et de l'annulation du téléchargement dans un adaptateur. Transformations d'images complexes avec une utilisation minimale de la mémoire. Mémoire automatique et mise en cache du disque.

Bibliothèque de Picasso Jake Wharton

Glide

Glide est un cadre de gestion des supports open source rapide et efficace pour Android qui englobe le décodage des supports, la mise en cache de la mémoire et du disque et le regroupement des ressources dans une interface simple et facile à utiliser.

Glide prend en charge la récupération, le décodage et l'affichage d'images fixes, d'images et de GIF animés. Glide comprend une API flexible qui permet aux développeurs de se connecter à presque n'importe quelle pile réseau. Par défaut, Glide utilise une pile personnalisée basée sur HttpUrlConnection, mais inclut également des bibliothèques d’utilitaires connectées au projet Volley de Google ou à la bibliothèque OkHttp de Square.

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

L'objectif principal de Glide est de rendre le défilement de toutes les listes d'images aussi fluide et rapide que possible, mais Glide est également efficace dans presque tous les cas où vous devez extraire, redimensionner et afficher une image distante.

bibliothèque de chargement d'images Glide

Fresque par Facebook

Fresco est un système puissant permettant d'afficher des images dans les applications Android.

Fresco s'occupe du chargement et de l'affichage des images, pour que vous n'ayez pas à le faire. Il charge les images du réseau, du stockage local ou des ressources locales et affiche un espace réservé jusqu'à l'arrivée de l'image. Il a deux niveaux de cache; un en mémoire et un autre en mémoire interne.

Fresque Github

Dans Android 4.x et versions antérieures, Fresco place les images dans une région particulière de la mémoire Android. Cela permet à votre application de s'exécuter plus rapidement et de subir beaucoup moins souvent l'effroyable erreur OutOfMemoryError.

Documentation Fresco

94
Ashwin S Ashok

Chargeur haute performance - après avoir examiné les méthodes suggérées ici, j'ai utilisé la solution de Ben avec quelques modifications -

  1. J'ai réalisé que travailler avec drawables est plus rapide qu'avec les bitmaps, donc j'utilise drawables à la place.

  2. Utiliser SoftReference est une bonne chose, mais l'image en mémoire cache est supprimée trop souvent. J'ai donc ajouté une liste liée contenant les références des images, empêchant ainsi la suppression de l'image jusqu'à ce qu'elle atteigne une taille prédéfinie.

  3. Pour ouvrir InputStream, j'ai utilisé Java.net.URLConnection, ce qui me permet d'utiliser le cache Web (vous devez d'abord définir un cache de réponses, mais c'est une autre histoire).

Mon 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

J'ai suivi cette Android formation et je pense que le téléchargement d’images est excellent, sans bloquer l’interface utilisateur principale. Il gère également la mise en cache et le défilement de nombreuses images: Chargement efficace de grandes images bitmap

77
toobsco42

1. Picasso permet des tracas chargement gratuit des images dans votre application, souvent dans une seule ligne de code!

Utilisez Gradle:

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

Juste une ligne de code!

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

2. Glide Une image en cours de chargement et bibliothèque de mise en cache pour Android axée sur le défilement régulier

Utilisez Gradle:

repositories {
  mavenCentral() 
  google()
}

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

// Pour une vue simple:

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

3. fresque est un système puissant pour afficher des images dans Android applications.Fresco se charge du chargement et de l'affichage des images, pour que vous n'ayez pas à le faire.

Bien démarrer avec Fresco

63
chiragkyada

J'ai écrit un didacticiel qui explique comment charger par la fenêtre des images dans une liste. Je vais dans quelques détails sur les questions de recyclage et de concurrence. J'utilise également un pool de threads fixe pour éviter de générer beaucoup de threads.

Chargement paresseux d'images dans Listview Tutorial

51
Ben Ruijl

Pour ce faire, je lance un fil permettant de télécharger les images en arrière-plan et de lui remettre un rappel pour chaque élément de la liste. Lorsque le téléchargement d’une image est terminé, elle appelle le rappel qui met à jour la vue de l’élément de la liste.

Cette méthode ne fonctionne cependant pas très bien lorsque vous recyclez des vues.

40
jasonhudgins

Je veux juste ajouter un autre bon exemple, adaptateurs XML. Comme il est utilisé par Google, j'utilise également la même logique pour éviter une erreur OutOfMemory.

En gros this ImageDownloader est votre réponse (car elle couvre la plupart de vos besoins). Vous pouvez également en implémenter certains.

31
Arslan Anwar

J'utilise NetworkImageView à partir du nouveau Android Volley Library com.Android.volley.toolbox.NetworkImageView et il semble fonctionner assez bien. Apparemment, il s'agit de la même vue que celle utilisée dans Google Play et dans d'autres nouvelles applications Google. Vaut vraiment le détour.

28
droidment

Il s'agit d'un problème courant sur Android qui a été résolu à bien des égards par de nombreuses personnes. À mon avis, la meilleure solution que j'ai vue est la bibliothèque relativement nouvelle appelée Picasso . Voici les faits saillants:

  • Source ouverte, mais dirigée par Jake Wharton de ActionBarSherlock gloire.
  • Chargement asynchrone d'images à partir de ressources réseau ou d'applications avec une seule ligne de code
  • Détection automatique ListView
  • Mise en cache automatique du disque et de la mémoire
  • Peut faire des transformations personnalisées
  • Beaucoup d'options configurables
  • API super simple
  • Fréquemment mis à jour
27
howettl

Le temps de chargement des images à partir d’Internet offre de nombreuses solutions. Vous pouvez également utiliser la bibliothèque Android-Query . Cela vous donnera toute l'activité requise. Assurez-vous de ce que vous voulez faire et lisez la page wiki de la bibliothèque. Et résolvez la restriction de chargement des images.

Ceci est mon 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;
}

Il devrait être résoudre votre problème de chargement paresseux.

25
Rahul Rawat

Je pense que ce problème est très populaire parmi les développeurs Android, et il existe de nombreuses bibliothèques de ce type qui prétendent résoudre ce problème, mais seules quelques-unes d’entre elles semblent être d'actualité. AQuery est l'une de ces bibliothèques, mais elle est meilleure que la plupart d'entre elles à tous les égards et vaut la peine d'être essayée.

24
Ritesh Kumar Dubey

Vous devez essayer ce chargeur universel est le meilleur. J'utilise ceci après avoir fait beaucoup de RnD sur un chargement paresseux.

niversal Image Loader

Caractéristiques

  • Chargement d'image multithread (asynchrone ou sync)
  • Large personnalisation de la configuration d'ImageLoader (exécuteurs de threads, téléchargeur, décodeur, mémoire cache et cache disque, options d'affichage des images, etc.)
  • Nombreuses options de personnalisation pour chaque appel d'image d'affichage (images de stub, commutateur de mise en cache, options de décodage, traitement et affichage de bitmap, etc.)
  • Mise en cache des images en mémoire et/ou sur disque (système de fichiers ou carte SD de l'appareil)
  • Processus de chargement d'écoute (y compris la progression du téléchargement)

Prise en charge d'Android 2.0+

enter image description here

21
Girish Patel

Jetez un oeil sur Shutterbug , le port léger SDWebImage (une belle bibliothèque sur iOS) d’Applidium sur Android. Il prend en charge la mise en cache asynchrone, stocke les URL ayant échoué, gère bien la concurrence et inclut des sous-classes utiles.

Les demandes d'extraction (et les rapports de bogues) sont également les bienvenues!

20
PatrickNLT

DroidParts a ImageFetcher ne nécessite aucune configuration pour pouvoir commencer.

  • Utilise un cache sur disque et en mémoire le moins récemment utilisé (LRU).
  • Décode efficacement les images.
  • Prend en charge la modification de bitmaps dans le fil d’arrière-plan.
  • A un fondu enchaîné simple.
  • A un rappel de progression de chargement de l'image.

Clone DroidPartsGram pour un exemple:

Enter image description here

16
yanchenko

Un petit conseil pour ceux qui sont indécis quant à la bibliothèque à utiliser pour les images à chargement paresseux:

Il y a quatre moyens de base.

  1. DIY => Pas la meilleure solution, mais pour quelques images et si vous voulez vous passer de la corvée d'utiliser d'autres bibliothèques

  2. Volley's Lazy Loading library => Des gars sur Android. C'est agréable et tout, mais est mal documenté et pose donc un problème d'utilisation.

  3. Picasso: Une solution simple qui fonctionne, vous pouvez même spécifier la taille exacte de l’image que vous souhaitez importer. C’est très simple à utiliser, mais elle risque de ne pas être très "performante" pour les applications qui doivent gérer des quantités énormes d’images.

  4. UIL: Le meilleur moyen de charger des images paresseux. Vous pouvez mettre en cache des images (vous devez bien sûr obtenir une autorisation), initialiser le chargeur une fois, puis terminer votre travail. La bibliothèque de chargement d'images asynchrones la plus mature que j'ai jamais vue jusqu'à présent.

16
Bijay Koirala

Novoda a également un super bibliothèque de chargement d'images paresseuses et de nombreuses applications comme Songkick, Podio, SecretDJ et ImageSearch utilisent leur bibliothèque.

Leur bibliothèque est hébergée ici sur Github et ils ont aussi un assez actif suivi des problèmes . Leur projet semble être assez actif aussi, avec plus de 300 engagements au moment de la rédaction de cette réponse.

15
Soham

Vérifiez mon fork de LazyList . En gros, j'améliore LazyList en retardant l'appel de ImageView et crée deux méthodes:

  1. Quand vous devez mettre quelque chose comme "Chargement de l'image ..."
  2. Lorsque vous devez afficher l'image téléchargée.

J'ai également amélioré ImageLoader en implémentant un singleton dans cet objet.

13
Nicolas Jafelle

Tous les codes ci-dessus ont leur propre valeur, mais avec mon expérience personnelle, essayez simplement avec Picasso.

Picasso est une bibliothèque spécialement conçue à cet effet. En fait, il gérera automatiquement le cache et toutes les autres opérations réseau. Vous devrez ajouter une bibliothèque à votre projet. et écrivez simplement une seule ligne de code pour charger l'image à partir d'une URL distante.

S'il vous plaît visitez ici: http://code.tutsplus.com/tutorials/Android-sdk-working-with-picasso--cms-22149

11
Akbar

Si vous souhaitez afficher la mise en page Shimmer comme Facebook, il existe une bibliothèque Facebook officielle à cet effet. FaceBook Shimmer Android

Il s’occupe de tout, il vous suffit de mettre le code de votre choix de manière imbriquée dans un cadre chatoyant. Voici un exemple de code.

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

Et voici le code Java pour cela.

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

Ajoutez cette dépendance dans votre fichier Gradle.

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

Voici à quoi ça ressemble . Shimmer Android screenshot

11
Zankrut Parmar

Utilisez la bibliothèque de glisse. Cela a fonctionné pour moi et fonctionnera aussi pour votre code. Cela fonctionne aussi bien pour les images que pour les 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

Donnez Aquery un essai. Il dispose de méthodes extrêmement simples pour charger et mettre en cache les images de manière asynchrone.

7
user2779311

Je peux recommander une méthode différente qui fonctionne comme un charme: Android Query.

Vous pouvez télécharger ce fichier JAR à partir de ici

AQuery androidAQuery = new AQuery(this);

Par exemple:

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

C'est très rapide et précis, et avec cela, vous pouvez trouver beaucoup plus de fonctionnalités comme l'animation lors du chargement, obtenir un bitmap (si nécessaire), etc.

7
Pratik Dasa

RLImageViewHelper est une bibliothèque étonnante qui vous aide à le faire.

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

Une autre façon de le faire consiste à utiliser votre adaptateur dans un thread de votre méthode getView ():

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();

bien sûr, vous devriez toujours mettre en cache vos images pour éviter des opérations supplémentaires, vous pouvez les placer dans un tableau HashMap, vérifier si l'image existe dans le tableau, sinon, continuer avec le fil ou bien charger l'image depuis votre tableau HashMap. Assurez-vous également toujours que vous ne perdez pas de mémoire, les bitmaps et les éléments dessinables sont souvent très chargés en mémoire. C'est à vous d'optimiser votre code.

4
Samet

J'ai eu ce problème et implémenté lruCache. Je crois que vous avez besoin de l’API 12 ou supérieure ou que vous utilisez la bibliothèque de compatibilité v4. lurCache est une mémoire rapide, mais elle a aussi un budget, donc si cela vous inquiète, vous pouvez utiliser un cache de disque ... Tout est décrit dans Caching Bitmaps.

Je vais maintenant fournir mon implémentation qui est un singleton J'appelle de n'importe où comme ceci:

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

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

Voici le code idéal pour mettre en cache, puis appeler ce qui précède dans getView d'un adaptateur lors de la récupération de l'image Web:

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

Vous pouvez essayer la bibliothèque Aquery Android pour le chargement paresseux d’images et de listview ... Le code ci-dessous peut vous aider ..... bibliothèque de téléchargement d'ici .

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

utilisez la classe ci-dessous pour télécharger et charger des images dans listview.Il met en cache chaque image une fois téléchargée. Charge également les images et le chargement paresseux.

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

J'utilise droidQuery . Il existe deux mécanismes pour charger une image à partir d'une URL. Le premier (raccourci) est simplement:

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

Ceci peut être ajouté très facilement dans la méthode getView(...) de ArrayAdapter.


La méthode longhand donnera beaucoup plus de contrôle et comporte des options qui ne sont même pas abordées ici (comme la mise en cache et les rappels), mais une implémentation de base spécifiant la taille de sortie de 200px x 200px peut être trouvée ici:

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

Certaines réponses ont déjà mentionné l'utilisation de diverses bibliothèques d'images telles que Universal Image Loader et androidimageloader, etc. Ceci est une vieille question, mais pour ceux qui recherchent encore quelque chose comme cela, il existe plusieurs bibliothèques de ce type pour le chargement/la mise en cache des images.

3
redGREENblue

Vous pouvez utiliser une bibliothèque tierce telle que Piccaso ou Volley pour un chargement paresseux efficace. Vous pouvez également créer le vôtre en implémentant ce qui suit.

  1. Implémenter le code pour télécharger l'image à partir de l'URL

  2. Implémentation d'un mécanisme de mise en cache pour stocker et récupérer des images (utilisez LruCache sur Android pour la mise en cache)

2
BalaramNayak

J'ai trouvé le Glide comme meilleure option que Picasso. J'utilisais picasso pour charger environ 32 images de taille environ 200-500KB chacune et j'obtenais toujours OOM. Mais le Glide a résolu tous mes problèmes OOM.

2
Sanjeet A

Vous pouvez utiliser AsyncImageView de GreenDroid. Il suffit d’appeler setUrl et j’imagine que cela pourrait vous aider à faire ce que vous ne voudriez pas faire et vous référer au lien ci-dessous:

lien pour asyncimageview de greenDroid

0
Imran

Sauf charger le cache de données de manière asynchrone, vous pouvez avoir besoin du cache d'interface utilisateur

Excepté le chargement des données d’éléments visibles, vous devrez peut-être charger les données d’approximable-visible

Exemple: supposons que l'élément visible dans la liste soit [6,7,8,9,10], vous devrez peut-être charger [6,7,8,9,10] ET pré-charger l'élément [1, 2, 3, 4 , 5] & [11, 12, 13, 14, 15], car l'utilisateur fait probablement défiler l'écran vers la page précédente ou la page suivante

0
Yessy