wake-up-neo.net

Caricamento lento delle immagini in ListView

Sto usando un ListView per mostrare alcune immagini e didascalie associate a quelle immagini. Sto ottenendo le immagini da Internet. C'è un modo per caricare le immagini in modo pigro così mentre il testo viene visualizzato, l'interfaccia utente non è bloccata e le immagini vengono visualizzate mentre vengono scaricate?

Il numero totale di immagini non è fisso.

1846
lostInTransit

Ecco cosa ho creato per contenere le immagini che la mia app sta attualmente visualizzando. Si noti che l'oggetto "Log" in uso qui è il mio wrapper personalizzato attorno alla classe Log finale all'interno di 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();
    }
}
1058
James A Wilson

Ho fatto una semplice demo di una lista pigra (che si trova su GitHub) con le immagini.

Utilizzo di base

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

Non dimenticare di aggiungere le seguenti autorizzazioni al tuo AndroidManifest.xml:

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

crea solo un'istanza di ImageLoader e riutilizzala tutta intorno all'applicazione. In questo modo il caching delle immagini sarà molto più efficiente.

Potrebbe essere utile a qualcuno. Scarica le immagini nel thread in background. Le immagini vengono memorizzate nella cache su una scheda SD e in memoria. L'implementazione della cache è molto semplice ed è sufficiente per la demo. Decodifico le immagini con inSampleSize per ridurre il consumo di memoria. Cerco anche di gestire correttamente le viste riciclate.

Alt text

1011
Fedor

Raccomando lo strumento open source Universal Image Loader. È originariamente basato sul progetto di Fedor Vlasov LazyList ed è stato notevolmente migliorato da allora.

  • Caricamento immagine multithread
  • Possibilità di regolazione ampia della configurazione di ImageLoader (thread executor, downlaoder, decoder, memoria e cache del disco, opzioni di visualizzazione delle immagini e altro)
  • Possibilità di memorizzazione nella cache delle immagini in memoria e/o sul file sysytem del dispositivo (o sulla scheda SD)
  • Possibilità di "ascoltare" il processo di caricamento
  • Possibilità di personalizzare ogni chiamata di immagini display con opzioni separate
  • Supporto per i widget
  • Supporto per Android 2.0+

546
nostra13

Multithreading For Performance , un tutorial di Gilles Debunne.

Questo è dal blog degli sviluppatori Android. Il codice suggerito utilizza:

  • AsyncTasks.
  • Una dimensione rigida e limitata, FIFO cache.
  • Una cache morbida e facilmente garbage collect-ed.
  • A segnaposto Drawable durante il download.

enter image description here

154
Thomas Ahle

Aggiornamento: nota che questa risposta è piuttosto inefficace ora. Il Garbage Collector agisce in modo aggressivo su SoftReference e WeakReference, quindi questo codice NON è adatto per le nuove app. (Invece, prova le librerie come Universal Image Loader suggerito in altre risposte.)

Grazie a James per il codice e Bao-Long per il suggerimento di utilizzare SoftReference. Ho implementato le modifiche di SoftReference sul codice di James. Sfortunatamente SoftReferences ha causato la raccolta dei dati inutilmente troppo rapidamente. Nel mio caso andava bene senza le cose di SoftReference, perché la mia lista di dimensioni è limitata e le mie immagini sono piccole.

C'è una discussione di un anno fa riguardante le SoftReferences sui gruppi di google: link to thread . Come soluzione alla raccolta dei rifiuti troppo precoce, suggeriscono la possibilità di impostare manualmente la dimensione dell'heap VM usando dalvik.system.VMRuntime.setMinimumHeapSize (), che per me non è molto attraente.

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

Picasso

Usa la Libreria Picasso di Jake Wharton. (Una libreria Perfect ImageLoading forma lo sviluppatore di ActionBarSherlock)

Una potente libreria di download e memorizzazione di immagini per Android.

Le immagini aggiungono il contesto e il fascino visivo necessari alle applicazioni Android. Picasso consente il caricamento delle immagini senza problemi nell'applicazione, spesso in un'unica riga di codice!

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

Molti errori comuni del caricamento delle immagini su Android sono gestiti automaticamente da Picasso:

Gestione del riciclaggio di ImageView e cancellazione del download in un adattatore. Trasformazioni complesse dell'immagine con un utilizzo minimo della memoria. Memoria automatica e memorizzazione nella cache del disco.

Libreria di Picasso Jake Wharton

Glide

Glide è un framework di gestione dei media open source veloce ed efficiente per Android che avvolge la decodifica dei media, la memoria e il caching del disco e il pooling delle risorse in un'interfaccia semplice e facile da usare.

Glide supporta il recupero, la decodifica e la visualizzazione di fermi immagine, immagini e GIF animate. Glide include una api flessibile che consente agli sviluppatori di collegarsi a quasi tutti gli stack di rete. Per impostazione predefinita, Glide utilizza uno stack basato su HttpUrlConnection personalizzato, ma include anche librerie di utilità plug-in nel progetto Volley di Google o nella libreria OkHttp di Square.

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

L'obiettivo principale di Glide è quello di far scorrere qualsiasi tipo di elenco di immagini nel modo più fluido e veloce possibile, ma Glide è efficace anche in quasi tutti i casi in cui è necessario recuperare, ridimensionare e visualizzare un'immagine remota.

Libreria di caricamento immagine Glide

Affresco di Facebook

Fresco è un potente sistema per la visualizzazione di immagini in applicazioni Android.

Affresco si occupa del caricamento e della visualizzazione delle immagini, quindi non è necessario. Caricherà le immagini dalla rete, dall'archivio locale o dalle risorse locali e visualizzerà un segnaposto finché l'immagine non sarà arrivata. Ha due livelli di cache; uno in memoria e un altro nella memoria interna.

Affresco Github

In Android 4.xe versioni precedenti, Fresco inserisce le immagini in una regione speciale della memoria Android. Ciò consente alla tua applicazione di funzionare più velocemente e subisce il temuto OutOfMemoryError molto meno spesso.

Documentazione dell'affresco

93
Ashwin S Ashok

Caricatore ad alte prestazioni - dopo aver esaminato i metodi suggeriti qui, ho usato la soluzione di Ben con alcune modifiche -

  1. Mi sono reso conto che lavorare con i drawable è più veloce di quello con bitmap, quindi uso invece drawable

  2. L'utilizzo di SoftReference è ottimo, ma rende l'immagine memorizzata nella cache troppo spesso, quindi ho aggiunto un elenco collegato che contiene riferimenti alle immagini, impedendo l'eliminazione dell'immagine, fino a raggiungere una dimensione predefinita

  3. Per aprire InputStream ho usato Java.net.URLConnection che mi permette di usare la cache Web (è necessario impostare prima una cache di risposta, ma questa è un'altra storia)

Il mio codice:

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

Ho seguito questo allenamento Android e penso che faccia un ottimo lavoro nel download delle immagini senza bloccare l'interfaccia utente principale. Gestisce anche il caching e si occupa dello scorrimento di molte immagini: Caricamento di bitmap di grandi dimensioni in modo efficiente

77
toobsco42

1. Picasso consente un uso senza problemi caricamento dell'immagine nella tua applicazione, spesso in una riga di codice!

Usa Gradle:

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

Solo una riga di codice!

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

2. Glide Un'immagine che carica e memorizza nella cache libreria per Android incentrata sullo scorrimento fluido

Usa Gradle:

repositories {
  mavenCentral() 
  google()
}

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

// Per una vista semplice:

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

3. affresco è un potente sistema per visualizzazione delle immagini nelle applicazioni Android. Fresco si occupa del caricamento e della visualizzazione delle immagini, quindi non è necessario.

Introduzione a Fresco

63
chiragkyada

Ho scritto un tutorial che spiega come eseguire il caricamento lazy delle immagini in un listview. Vado in alcuni dettagli sulle questioni del riciclaggio e della concorrenza. Uso anche un pool di thread fisso per evitare di generare molti thread.

Caricamento pigro delle immagini in Listview Tutorial

51
Ben Ruijl

Il modo in cui lo faccio è lanciando una discussione per scaricare le immagini in background e consegnarle una callback per ogni voce dell'elenco. Al termine del download, viene richiamata la richiamata che aggiorna la vista per la voce dell'elenco.

Tuttavia, questo metodo non funziona molto bene quando stai riciclando le visualizzazioni.

39
jasonhudgins

Voglio solo aggiungere un altro buon esempio, Adattatori XML. Come è utilizzato da Google e sto anche usando la stessa logica per evitare un errore OutOfMemory.

Fondamentalmente questo ImageDownloader è la tua risposta (poiché copre la maggior parte delle tue esigenze). Alcuni si possono anche implementare in questo.

31
Arslan

Ho usato NetworkImageView dalla nuova libreria Android Volley com.Android.volley.toolbox.NetworkImageView, e sembra funzionare abbastanza bene. Apparentemente, questa è la stessa vista utilizzata in Google Play e altre nuove applicazioni Google. Sicuramente vale la pena dare un'occhiata.

28
droidment

Questo è un problema comune su Android che è stato risolto in molti modi da molte persone. A mio parere, la soluzione migliore che ho visto è la relativamente nuova libreria chiamata Picasso . Ecco i punti salienti:

  • Open source, ma guidato da Jake Wharton di ActionBarSherlock fame.
  • Carica in modo asincrono le immagini da risorse di rete o di app con una sola riga di codice
  • Rilevamento automatico ListViewname__
  • Memorizzazione automatica nella cache del disco e della memoria
  • Può fare trasformazioni personalizzate
  • Molte opzioni configurabili
  • API super semplice
  • Frequentemente aggiornato
27
howettl

Bene, il tempo di caricamento delle immagini da Internet ha molte soluzioni. Puoi anche utilizzare la libreria Android-Query . Ti darà tutta l'attività richiesta. Assicurati cosa vuoi fare e leggi la pagina wiki della libreria. E risolvi la restrizione del caricamento dell'immagine.

Questo è il mio codice:

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

Dovrebbe essere risolvere il tuo problema di caricamento pigro.

25
Rahul Rawat

Penso che questo problema sia molto popolare tra gli sviluppatori Android, e ci sono un sacco di librerie del genere che pretendono di risolvere questo problema, ma solo alcune sembrano essere sul punto. AQuery è una di queste librerie, ma è meglio della maggior parte di esse in tutti gli aspetti e vale la pena provarci.

24

Devi provare questo Universal Loader è il migliore. Sto usando questo dopo aver fatto molti RnD sul caricamento pigro.

Universal Image Loader

Caratteristiche del libro

  • Caricamento di immagini multithread (asincrono o sincronizzazione)
  • Ampia personalizzazione della configurazione di ImageLoader (thread executors, downloader, decoder, memoria e cache del disco, opzioni di visualizzazione delle immagini, ecc.)
  • Molte opzioni di personalizzazione per ogni chiamata di immagini di visualizzazione (immagini stub, interruttore di memorizzazione nella cache, opzioni di decodifica, elaborazione e visualizzazione di Bitmap, ecc.)
  • Memorizzazione nella cache delle immagini in memoria e/o su disco (file system del dispositivo o scheda SD)
  • Ascolto del processo di caricamento (incluso lo stato di download)

Supporto per Android 2.0+

enter image description here

21
Girish Patel

Dai un'occhiata a Shutterbug , la porta leggera di Applidium SDWebImage (una libreria su iOS) ad Android. Supporta il caching asincrono, memorizza gli URL non riusciti, gestisce bene la concorrenza e sono incluse sottoclassi utili.

Anche le richieste di pull (e le segnalazioni di bug) sono benvenute!

20
PatrickNLT

DroidParts ha ImageFetcher che richiede zero configurazione per iniziare.

  • Utilizza un disco e in-memory Least Recently Used (LRU) cache.
  • Decodifica in modo efficiente le immagini.
  • Supporta la modifica di bitmap nel thread in background.
  • Ha una dissolvenza incrociata semplice.
  • Ha il richiamo dell'avanzamento del caricamento dell'immagine.

Clone DroidPartsGram per un esempio:

Enter image description here

16
yanchenko

Solo un suggerimento per chi è indeciso su quale libreria usare per le immagini con caricamento lento:

Ci sono quattro modi di base.

  1. Fai da te => Non è la soluzione migliore ma per poche immagini e se vuoi andare senza il fastidio di usare le librerie di altri

  2. Libreria di caricamento pigro di Volley => Da ragazzi su Android. È bello e tutto ma è scarsamente documentato e quindi è un problema da usare.

  3. Picasso: una soluzione semplice che funziona, puoi persino specificare l'esatta dimensione dell'immagine che vuoi portare. È molto semplice da usare ma potrebbe non essere molto "performante" per le app che devono gestire quantità enormi di immagini.

  4. UIL: il modo migliore per caricare le immagini pigre. È possibile memorizzare le immagini nella cache (è necessario il permesso, ovviamente), inizializzare il caricatore una volta, quindi eseguire il lavoro. La più matura libreria di caricamento di immagini asincrone che abbia mai visto finora.

16
Bijay Koirala

Novoda ha anche una fantastica libreria di caricamento delle immagini e molte app come Songkick, Podio, SecretDJ e ImageSearch usano la loro libreria.

La loro libreria è ospitata qui su Github e hanno un tracker di problemi abbastanza attivo anche. Il loro progetto sembra essere piuttosto attivo, con oltre 300 commit al momento di scrivere questa risposta.

15
Soham

Controlla il mio fork di LazyList . Fondamentalmente, ho migliorato LazyList ritardando la chiamata di ImageView e creando due metodi:

  1. Quando devi inserire qualcosa come "Caricamento immagine ..."
  2. Quando è necessario mostrare l'immagine scaricata.

Ho anche migliorato ImageLoader implementando un singleton in questo oggetto.

13
Nicolas Jafelle

Tutti i codici di cui sopra hanno il loro valore, ma con la mia esperienza personale provate con Picasso.

Picasso è una libreria specifica per questo scopo, infatti gestirà automaticamente la cache e tutte le altre operazioni di rete. Dovrai aggiungere una libreria nel tuo progetto e scrivere una sola riga di codice per caricare l'immagine dall'URL remoto.

Per favore visita qui: http://code.tutsplus.com/tutorials/Android-sdk-working-with-picasso--cms-22149

11
Akbar

Se vuoi visualizzare il layout Shimmer come Facebook, c'è una libreria ufficiale di Facebook per questo. FaceBook Shimmer Android

Si prende cura di tutto, Hai solo bisogno di mettere il codice di progettazione desiderato in modo annidato nel telaio shimmer. Ecco un codice di esempio.

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

Ed ecco il codice Java per questo.

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

Aggiungi questa dipendenza nel tuo file gradle.

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

Ecco come appare. Shimmer Android screenshot

10
Zankrut Parmar

Usa la libreria di glide. Ha funzionato per me e funzionerà anche per il tuo codice. Funziona sia per le immagini che per le gif.

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

Dare Aquery una prova. Ha metodi sorprendentemente semplici per caricare e memorizzare le immagini in modo asincrono.

7
user2779311

Posso consigliare un modo diverso che funzioni come un fascino: Android Query.

Puoi scaricare il file JAR da qui

AQuery androidAQuery = new AQuery(this);

Come esempio:

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

È molto veloce e preciso, e usando questo puoi trovare molte altre funzionalità come l'animazione durante il caricamento, ottenere una bitmap (se necessaria), ecc.

7
Pratik Dasa

URLImageViewHelper è una straordinaria libreria che ti aiuta a farlo.

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

Un altro modo per farlo è attraverso l'adattatore in una discussione nel metodo 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();

ovviamente, dovresti sempre memorizzare le immagini in cache per evitare operazioni extra, potresti mettere le tue immagini in un array HashMap, controllare se l'immagine esiste nell'array, altrimenti, procedere con il thread o altrimenti caricare l'immagine dall'array HashMap. Inoltre controlla sempre che non si stia perdendo memoria, bitmap e drawable sono spesso pesanti in memoria. Spetta a te ottimizzare il tuo codice.

4
Samet

Ho avuto questo problema e implementato lruCache. Credo che tu abbia bisogno dell'API 12 o superiore o che usi la libreria v4 compatibile. lurCache è una memoria veloce, ma ha anche un budget, quindi se sei preoccupato di ciò puoi usare una cache del disco ... È tutto descritto in Bitmap di caching.

Ora fornirò la mia implementazione che è un singleton che chiamo da qualsiasi parte in questo modo:

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

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

Ecco il codice ideale da memorizzare nella cache e quindi richiamare quanto sopra in getView di un adattatore quando si recupera l'immagine 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

Puoi provare la libreria Aquery Android per l'immagine lazy loading e listview ... Il codice qui sotto può aiutarti ..... scarica la libreria da qui .

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

usa sotto la classe per scaricare e caricare le immagini in listview.It memorizza nella cache tutte le immagini una volta scaricato. Carica anche le immagini ad un caricamento lazy.

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

Io uso droidQuery . Esistono due meccanismi per caricare un'immagine da un URL. Il primo (stenografia) è semplicemente:

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

Questo può essere aggiunto facilmente in un metodo getView(...) di ArrayAdapter.


Il metodo longhand darà molto più controllo e ha opzioni che non sono nemmeno discusse qui (come cache e callback), ma un'implementazione di base che specifica la dimensione di output come 200px x 200px può essere trovata qui:

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

Alcune risposte sono già state citate usando varie librerie di immagini come Universal Image Loader e Androidimageloader ecc. Questa è una vecchia domanda, ma per chiunque sia ancora alla ricerca di qualcosa del genere, ci sono diverse librerie del genere per il caricamento/caching delle immagini.

3
redGREENblue

Puoi utilizzare alcune librerie di terze parti come Piccaso o Volley per un caricamento lazy efficace. Puoi anche crearne uno implementando il seguente

  1. Implementare il codice per scaricare l'immagine dall'URL

  2. Implementare il meccanismo di memorizzazione nella cache per l'archiviazione e il recupero dell'immagine (utilizzare LruCache di Android per la memorizzazione nella cache)

2
BalaramNayak

Ho trovato il Glide come opzione migliore di Picasso. Stavo usando Picasso per caricare circa 32 immagini di dimensioni intorno a 200-500KB ciascuna e ricevevo sempre OOM. Ma Glide ha risolto tutti i miei problemi OOM.

2
Sanjeet A

È possibile utilizzare AsyncImageView di GreenDroid. Basta chiamare setUrl e credo che questo potrebbe aiutare a fare la cosa che non vuoi fare e riferirti a questo link dato di seguito:

collegamento per asyncimageview di greenDroid

0
Imran

Tranne il caricamento della cache di dati in modo asincrono, potrebbe essere necessaria la cache dell'interfaccia utente

Tranne il caricamento dei dati degli articoli visibili, potrebbe essere necessario caricare i dati relativi all'elemento visibile approssimativamente

Esempio: Supponiamo che l'elemento visibile listview sia [6,7,8,9,10], potresti dover caricare [6,7,8,9,10] E precaricare l'elemento [1, 2, 3, 4 , 5] e [11, 12, 13, 14, 15], perché l'utente probabilmente scorre fino alla pre-pagina o alla pagina successiva

0
Yessy