Android'de ListView'da görüntüleri nasıl tembel olarak yükleyebilirim?


1931

Ben kullanıyorum ListViewbu görüntülerle ilgili bazı görüntülerin ve başlıkları görüntüleme. Görüntüleri internetten alıyorum. Metinleri görüntülerken, kullanıcı arayüzü engellenmez ve resimler indirildikçe görüntülenirken görüntüleri tembel olarak yüklemenin bir yolu var mı?

Toplam görüntü sayısı sabit değildir.


10
GreenDroid'in AsyncImageView uygulamasını kullanabilirsiniz . Sadece ara setUrl.
Pascal Dimassimo

7
Ben kullandım. Harika bir uygulama. AsyncImageView, büyük bir GreenDroid projesinin bir parçası olduğu için kötü bir haber. Ayrıca, GreenDroid projesi 2011'den beri güncellenmiyor.
borisstr

5
Bu kütüphaneyi bile deneyebilirsiniz: Bence görüntülerin asenkron yüklenmesi için en iyisi olan Android-http-image-manager .
Ritesh Kumar Dubey

34
Sadece Picasso'yu kullanın, her şeyi kendisi yapacak. 'Picasso.with (yourContext) .load (img src / yol / burada çizilebilir) .into (imageView yani hedefiniz);' Bu kadar!
Anuj Sharma

6
kullanmayı deneyin: github.com/nostra13/Android-Universal-Image-Loader , bu kütüphane tembel yükleme ve görüntü önbellekleme için çok hızlı ve etkilidir
krunal patel

Yanıtlar:


1087

Uygulamamın şu anda görüntülediği resimleri tutmak için oluşturduğum şey. Burada kullanılan "Log" nesnesinin Android içindeki son Log sınıfının etrafındaki özel paketleyicim olduğunu lütfen unutmayın.

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

104
Programınızın hiçbir zaman OutOfMemoryException'a neden olmaması için SoftReferences kullanmanız gerektiğini düşünüyorum. GC, yığın boyutu arttığında yazılım referanslarını temizleyebildiğinden ... birkaç saniye sonra resimlerinizi bu listeye koyabileceğiniz ve yüklemeden önce resim varsa tekrar indirmediğinizi kontrol etmelisiniz. bu listeden ve ayrıca softref listenize geri koyarak ve bir süre sonra hardlistinizi temizleyebilirsiniz :)
AZ_

36
Google Rafları projesi, code.google.com/p/shelves
AZ_

12
DrawableMap görüntüyü içerdiğinde ... getirme iş parçacığını başlatmadan bir dönüşü kaçırmaz mısınız?
Karussell

5
Bu kodun birkaç sorunu var. Öncelikle bellek sızıntısına neden olacak Drawable'ları önbelleğe almalısınız: stackoverflow.com/questions/7648740/… . İkincisi, önbelleğin kendisi asla temizlenmez, böylece sonsuza kadar büyür, bu başka bir bellek sızıntısıdır.
satur9nine


1025

Görüntülerle tembel bir listenin (GitHub'da) basit bir demosunu yaptım .

Temel Kullanım

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

AndroidManifest.xml'nize aşağıdaki izinleri eklemeyi unutmayın:

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

yalnızca bir ImageLoader örneği oluşturun ve uygulamanızın her yerinde yeniden kullanın. Bu şekilde görüntü önbelleklemesi çok daha verimli olacaktır.

Birisi için yararlı olabilir. Arka plan iş parçacığındaki görüntüleri indirir. Görüntüler bir SD kartta ve bellekte önbelleğe alınıyor. Önbellek uygulaması çok basittir ve demo için yeterlidir. Bellek tüketimini azaltmak için inSampleSize ile görüntüleri çözerim. Ayrıca geri dönüştürülmüş görünümleri doğru şekilde ele almaya çalışıyorum.

Alternatif metin


7
Teşekkürler,
projemin

3
Herkes alternatif olarak Gilles Debunne koduna baktı. Gördüğüm iki büyük fark 1) SD karta karşı bellek önbelleklemede ve 2) bir iş parçacığı havuzu yerine AsyncTasks kullanımıdır. android-developers.blogspot.com/2010/07/…
Richard

4
Bir hata var, bazen ateşleniyor: 10-13 09: 58: 46.738: ERROR / AndroidRuntime (24250): Yakalanmayan işleyici: yakalanmayan istisna nedeniyle ana iplik çıkışı 10-13 09: 58: 46.768: ERROR / AndroidRuntime (24250) : java.lang.ArrayIndexOutOfBoundsException: Dizi dizini aralık dışında: 0 10-13 09: 58: 46.768: ERROR / AndroidRuntime (24250): at java.util.Vector.elementAt (Vektör.java:331) 10-13 09: 58: 46.768: HATA / AndroidRuntime (24250): java.util.Vector.get (Vector.java:445) 10-13 09: 58: 46.768: ERROR / AndroidRuntime (24250): com.my.app.image'de .ImageLoader $ PhotosQueue.Clean (ImageLoader.java:91)
Mikooos

64
Bu kodu kendi projenize eklemek istiyorsanız, manifest'e harici önbellek izinleri eklemeniz gerektiğini benim gibi yeni başlayanlar için eklemek istiyorum. Teşekkür ederim
Adam

2
@BruceHill En son kaynak kodunda hiç photoQueue yok. Çok eski bir sürüm kullanıyor gibisin.
Fedor

552

Açık kaynaklı enstrüman Universal Image Loader'ı öneririm . Başlangıçta Fedor Vlasov'un LazyList projesine dayanıyor ve o zamandan beri büyük ölçüde geliştirildi.

  • Çok iş parçacıklı görüntü yükleme
  • Geniş ayarlama ImageLoader yapılandırması (iş parçacığı yürütücüler, indirme, kod çözücü, bellek ve disk önbelleği, ekran görüntü seçenekleri ve diğerleri)
  • Bellekte ve / veya cihazın dosya sisteminde (veya SD kartında) görüntü önbellekleme olasılığı
  • Yükleme işlemini "dinleme" imkanı
  • Her ekran görüntüsü çağrısını ayrı seçeneklerle özelleştirme imkanı
  • Widget desteği
  • Android 2.0+ desteği


16
yaratıcısının değerli bebeği (sadece tek seferlik bir çözüm değil) gibi davrandığı ve koruduğu harika "resim yükleme" kodu arıyorsanız, u sadece buldum; büyük ups Nostra
AndroidGecko

Gerçekten harika bir iş, ama benim liste görünümü biraz gecikiyor. En iyi performans 'ImageLoader' yapı söyleyebilir ... ya da belki de 'DisplayImageOptions' çünkü.
dinigo

Bu gridview'i çok seviyorum ama eğitimim için kullanamıyorum. Ben android bir acemi değilim. Ben gridview hakkında uygulama yapmak ama benim uygulama targetSdkVersion 15 oldu, bu yüzden arka plan iş parçacığında işlem için Asynctask kullanmanız gerekir. Eskiden bu tablo görünümünü kullanıyordum ama çalışmıyor. targetSdkVersion 15'te nasıl kullanabilirim?
kongkea

[Universal-image-loader]
nostra13

3
Resmi android belgelerini okuduktan ve bu şeyleri kendim yapmaya çalıştıktan sonra, bu kütüphanenin tümünün resim yüklemesinin sonu olacağından eminim. Yeterince oy kullanılamıyor.
Çekirdek

159

Performans için Multithreading , Gilles Debunne tarafından bir eğitim.

Bu Android Geliştiricileri Blogu'ndan. Önerilen kod şunları kullanır:

  • AsyncTasks.
  • Sert, sınırlı bir boyut FIFO cache,.
  • Yumuşak, kolay garbage collectokunan bir önbellek.
  • İndirirken bir yer tutucuDrawable .

resim açıklamasını buraya girin


10
2.1 de iyi çalışıyor. Sadece AndroidHttpClient kullanmayın.
Thomas Ahle

2
@ thomas-ahle Teşekkür ederim, AndroidHttpClient'in 2.2'de uygulandığı için hata verdiğini gördüm, ancak 2.2'den başka bir şey bulmaya çalışmadım.
Adinia

4
@Adina Haklısın, unuttum. Ancak tarifte normal bir HttpClient ile yapılabilecek hiçbir şey yoktur.
Thomas Ahle

Android çekirdeği, sistemin önceki sürümlerine kıyasla bu referansları toplamak için çok istekli olduğu için Google'ın yumuşak referanslar önermediğini birkaç yerde duydum.
Muhammed Ahmed AbuTalib

109

Güncelleme: Bu cevabın şimdi oldukça etkisiz olduğunu unutmayın. Çöp Toplayıcı SoftReference ve WeakReference üzerinde agresif bir şekilde çalışır, bu nedenle bu kod yeni uygulamalar için uygun DEĞİLDİR. (Bunun yerine, diğer yanıtlarda önerilen Universal Image Loader gibi kitaplıkları deneyin .)

Kod için James'e ve SoftReference kullanma önerisi için Bao-Long'a teşekkürler. James'in kodunda SoftReference değişikliklerini uyguladım. Ne yazık ki SoftReferences görüntülerimin çok hızlı bir şekilde çöp toplanmasına neden oldu. Benim durumumda, SoftReference materyalleri olmadan iyiydi, çünkü liste boyutum sınırlı ve resimlerim küçük.

Bir yıl önce google gruplarındaki SoftReferences ile ilgili bir tartışma var: link to thread . Çok erken çöp toplama için bir çözüm olarak, VM yığın boyutunu manuel olarak benim için çok çekici olmayan dalvik.system.VMRuntime.setMinimumHeapSize () kullanarak ayarlama olasılığını öneriyorlar.

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

3
sert üretim ve yumuşatma gibi nesiller oluşturabilirsiniz. 3 saniye içinde erişilmeyen tüm görüntüleri temizleyecek bir önbelleği düzeltebilirsiniz .. google rafları projesine bir göz
atabilirsiniz

developer.android.com/reference/java/lang/ref/… SoftReference dokümanının önbellekleme hakkında bir notu vardır, "Önbellekleme için Yumuşak Referanslardan Kaçının" bölümüne bakın. Çoğu uygulama yumuşak referanslar yerine android.util.LruCache kullanmalıdır.
vokilam

Koduna hayranım ama şimdi yeni Android O / S'de 'agresif' çöp toplama var. Zayıf bir referansa sahip olmak benim için bir anlam ifade etmiyor.
j2emanue

@ j2emanue Haklısın, cevabımın en üstünde belirtmeye çalıştığım için, SoftReferences çok çabuk toplanan çöp. Bunu daha da netleştirmek için bu cevabı düzenlemeye çalışacağım.
TalkLittle

97

Picasso

Jake Wharton'un Picasso Kütüphanesini kullanın. (Mükemmel bir ImageLoading Kütüphanesi, ActionBarSherlock geliştiricisini oluşturur)

Android için güçlü bir görüntü indirme ve önbellek kütüphanesi.

Görüntüler, Android uygulamalarına çok ihtiyaç duyulan bağlam ve görsel yetenek katıyor. Picasso, uygulamanızda sorunsuz bir şekilde resim yüklemeye olanak tanır - genellikle tek bir kod satırında!

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

Android'de resim yüklemenin birçok yaygın tuzağı Picasso tarafından otomatik olarak ele alınır:

Bir bağdaştırıcıda ImageView geri dönüşüm ve indirme iptalini kullanma. Minimum bellek kullanımı ile karmaşık görüntü dönüşümleri. Otomatik bellek ve disk önbellekleme.

Picasso Jake Wharton Kütüphanesi

yarı ünlü

Glide, Android için medya kod çözme, bellek ve disk önbellekleme ve kaynak havuzlamayı basit ve kullanımı kolay bir arayüze saran hızlı ve verimli bir açık kaynaklı medya yönetim çerçevesidir.

Glide, video görüntüleri, görüntüler ve animasyonlu GIF'lerin getirilmesini, kodunun çözülmesini ve görüntülenmesini destekler. Glide, geliştiricilerin neredeyse tüm ağ yığınlarına bağlanmasına izin veren esnek bir API içerir. Glide varsayılan olarak özel bir HttpUrlConnection tabanlı yığın kullanır, ancak bunun yerine Google'ın Volley projesine veya Square'in OkHttp kütüphanesine takılan yardımcı program kitaplıkları da içerir.

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

Glide'ın ana odağı, herhangi bir görüntü listesini kaydırmayı olabildiğince pürüzsüz ve hızlı hale getirmektir, ancak Glide, uzak bir görüntüyü getirmeniz, yeniden boyutlandırmanız ve görüntülemeniz gereken hemen hemen her durumda etkilidir.

Glide Görüntü Yükleme Kütüphanesi

Facebook tarafından Fresk

Fresco, Android uygulamalarında görüntüleri görüntülemek için güçlü bir sistemdir.

Fresco, görüntü yükleme ve görüntüleme işlemlerini halleder, böylece zorunda kalmazsınız. Ağdan, yerel depodan veya yerel kaynaklardan görüntü yükler ve görüntü gelene kadar bir yer tutucu görüntüler. İki önbellek seviyesi vardır; biri bellekte, diğeri dahili depolamada.

Fresco Github

Android 4.x ve önceki sürümlerde, Fresco görüntüleri Android belleğinin özel bir bölgesine yerleştirir. Bu, uygulamanızın daha hızlı çalışmasını sağlar ve korkunç OutOfMemoryError'ı daha az sıklıkta çeker.

Fresco Belgeleri


Picasso Meydanı'nda tarafından geliştirilen bir kütüphane
LordRaydenMK

83

Yüksek performanslı yükleyici - burada önerilen yöntemleri inceledikten sonra Ben'in çözümünü bazı değişikliklerle kullandım -

  1. Çekmecelerle çalışmanın bitmap'lerden daha hızlı olduğunu fark ettim, bunun yerine çekmeceleri kullandım

  2. SoftReference kullanmak harika, ancak önbelleğe alınan görüntünün çok sık silinmesini sağlıyor, bu yüzden önceden tanımlanmış bir boyuta ulaşana kadar görüntünün silinmesini önleyerek görüntü referanslarını tutan bir Bağlantılı liste ekledim

  3. InputStream'i açmak için web önbelleğini kullanmama izin veren java.net.URLConnection kullandım (önce bir yanıt önbelleği ayarlamanız gerekir, ancak bu başka bir hikaye)

Kodum:

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

Harika çalışıyor! BTW sınıf adında bir yazım hatası var.
Mullins

5
Başka birine zaman kazandırırsa: 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;
Michael Reed

Çok teşekkürler, bu güzel bir uygulama. Ayrıca, kullanıcı çekilebileceği şekilde çekilebilir kağıt yüklenirken farklı bir yer tutucu koydum.
Juan Hernandez

Ayrıca varsayılan FIFO yerine executorService (mThreadPool) bir LIFO kuyruğu kullanmak daha iyi olduğunu düşünüyorum böylece istenen son görüntüler (muhtemelen görünür olanlar) ilk yüklenir. Bkz. Stackoverflow.com/questions/4620061/how-to-create-lifo-executor
Juan Hernandez

9
@MichaelReed, eğer bir Eclipse kullanıcısıysanız, Ctrl-Shift-O kullanmanızı öneririz (bu O harfi değil, 0 rakamıdır). İthalat ekleme işlemini otomatik hale getirir ve sizin için düzenler. Mac kullanıyorsanız, bunun yerine Command-Shift-O kullanın.
SilithCrowe

78

Bu Android Eğitimini takip ettim ve ana kullanıcı arayüzünü engellemeden resimleri indirmede mükemmel bir iş çıkardığını düşünüyorum. Ayrıca önbellekleme ve birçok görüntüde kaydırma ile başa çıkma işlemlerini gerçekleştirir: Büyük Bitmap'leri Verimli Yükleme


Maalesef, Google IO uygulaması için yalnızca tek bir sınıfa işaret ettim (ve düzenlemek için çok geç kaldım). Önbellek sınıfıyla aynı pakette bulabileceğiniz tüm görüntü yükleme ve önbelleğe alma yardımcı programı sınıflarını gerçekten incelemelisiniz .
mkuech

Herkes liste görünümü için görüntü yükleme / önbellek işleme yardımcı olmak için iosched app util klasöründen DiskLruCache, Image * .java dosyaları kapmak için tavsiye eder misiniz? Demek istediğim, konu hakkındaki çevrimiçi Geliştirici kılavuzlarını takip etmeye değer ama bu sınıflar (iosched'ten) desenle biraz daha ilerliyor.
Nisan'ta Gautam

65

1. Picasso , uygulamanızda sorunsuz bir şekilde resim yüklemeye izin verir - genellikle bir kod satırında!

Gradle kullanın:

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

Sadece bir satır kod!

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

2. Glide Düzgün kaydırmaya odaklanan Android için bir görüntü yükleme ve önbellek kütüphanesi

Gradle kullanın:

repositories {
  mavenCentral() 
  google()
}

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

// Basit bir görünüm için:

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

3. fresk , Android uygulamalarında görüntüleri görüntülemek için güçlü bir sistemdir.

Fresk ile Başlarken


Bu eğitim PICASOO için size daha fazla yardımcı olabilir: - androidtutorialshub.com/… ve GLIDE : - androidtutorialshub.com/…
lalit vasan

52

Liste görünümünde görüntülerin tembel olarak nasıl yükleneceğini açıklayan bir eğitici yazdım. Geri dönüşüm ve eşzamanlılık konularında biraz ayrıntıya giriyorum. Ayrıca bir çok iş parçacığının ortaya çıkmasını önlemek için sabit bir iş parçacığı havuzu kullanıyorum.

Listview Eğitiminde görüntülerin tembel yüklenmesi


41

Bunu yapmanın yolu, arka planda görüntüleri indirmek ve her liste öğesi için bir geri arama vermek için bir iş parçacığı başlatmaktır. Bir resim indirmeyi tamamladığında, liste öğesinin görünümünü güncelleyen geri aramayı çağırır.

Ancak görünümleri geri dönüştürürken bu yöntem çok işe yaramaz.


her görüntü için bir iplik kullanmak benim de kullandığım yaklaşım. Modelinizi görünümünüzden ayırırsanız, modeli önbelleğe almak için Etkinlik dışında ('uygulama' sınıfınızda olduğu gibi) devam ettirebilirsiniz. Çok sayıda resminiz varsa kaynaklarınız tükenmemeye dikkat edin.
James A Wilson

lütfen biraz açar mısın? Android geliştirmede yeniyim. İpuçları için teşekkürler
lostInTransit

14
Her görüntü için yeni bir iş parçacığı başlatmak etkili bir çözüm değildir. Bellek ve dondurma kullanıcı arayüzünde çok sayıda iş parçacığıyla sonuçlanabilir.
Fedor

Fedor, kabul etti, genellikle bir kuyruk ve bir iş parçacığı havuzu kullanıyorum, bu imo'ya gitmenin en iyi yolu.
jasonhudgins


29

Bu, Android'de birçok kişi tarafından birçok şekilde çözülen yaygın bir sorundur. Bence gördüğüm en iyi çözüm, Picasso adında nispeten yeni bir kütüphane . İşte önemli noktalar:

  • Açık kaynak, ancak tarafından başkanlığında Jake Whartonbir ActionBarSherlock ün.
  • Tek bir kod satırı ile ağ veya uygulama kaynaklarından eşzamansız olarak resim yükleyin
  • Otomatik ListViewalgılama
  • Otomatik disk ve bellek önbellekleme
  • Özel dönüşümler yapabilir
  • Birçok yapılandırılabilir seçenek
  • Süper basit API
  • Sık güncellenen

29

Yeni Android Voleybolu Kütüphanesi'nden NetworkImageView kullanıyorum com.android.volley.toolbox.NetworkImageViewve oldukça iyi çalışıyor gibi görünüyor. Görünüşe göre, bu, Google Play ve diğer yeni Google uygulamalarında kullanılan görünümle aynıdır . Kesinlikle kontrol etmeye değer.


1
Bu en iyi çözüm olduğunu düşünüyorum - diğer cevaplar çok eski - voleybolu gerçekten hızlı ve jake warthons disklrucache ile birlikte onun bir perfekt çözüm - ben başkalarını çok denedim ama bir voleybol gibi istikrarlı ve hızlı
Alexander Sidikov Pfeif

26

İnternetten görüntü yükleme süresinin birçok çözümü var. Android-Query kitaplığını da kullanabilirsiniz . Size gerekli tüm aktiviteyi verecektir. Ne yapmak istediğinizden emin olun ve kütüphane wiki sayfasını okuyun. Ve resim yükleme kısıtlamasını çözün.

Bu benim kodum:

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

Tembel yükleme probleminizi çözmelisiniz.


Bana iyi iş, ama projenize dahil etmek için bir Jar dosyasına ihtiyacınız var. Bu JAR dosyasını buradan indirebilirsiniz AQuery androidAQuery = new AQuery (this); bağlantı mı: code.google.com/archive/p/android-query/downloads
Selim Raza

25

Bu sorunun Android geliştiricileri arasında çok popüler olduğunu düşünüyorum ve bu sorunu çözdüğünü iddia eden çok sayıda kütüphane var, ancak bunlardan sadece birkaçı markette görünüyor. AQuery böyle bir kütüphanedir, ancak her yönüyle çoğundan daha iyidir ve denemeye değer.


22

Bu Evrensel Yükleyicinin en iyisi olduğunu denemelisiniz. Ben tembel yükleme üzerinde birçok RnD yaptıktan sonra kullanıyorum.

Evrensel Görüntü Yükleyici

Özellikleri

  • Çok iş parçacıklı görüntü yükleme (zaman uyumsuzluk veya senkronizasyon)
  • ImageLoader yapılandırmasının geniş çapta özelleştirilmesi (iş parçacığı yürütücüleri, indirici, kod çözücü, bellek ve disk önbelleği, ekran görüntüsü seçenekleri vb.)
  • Her görüntülü arama için birçok özelleştirme seçeneği (saplama görüntüleri, önbellek anahtarı, kod çözme seçenekleri, Bitmap işleme ve görüntüleme vb.)
  • Bellekte ve / veya diskte görüntü önbelleğe alma (cihazın dosya sistemi veya SD kartı)
  • Dinleme yükleme işlemi (indirme işlemi dahil)

Android 2.0+ desteği

resim açıklamasını buraya girin


20

Applidium'un hafif SDWebImage (iOS'ta güzel bir kütüphane) bağlantı noktası olan Shutterbug'a bir göz atın . Eşzamansız önbelleğe almayı destekler, başarısız URL'leri depolar, eşzamanlılığı iyi işler ve yardımcı alt sınıflar dahildir.

Çekme istekleri (ve hata raporları) da kabul edilir!


16

DroidParts , başlamak için sıfır yapılandırma gerektiren ImageFetcher'a sahiptir .

  • Disk ve bellek içi En Son Kullanılan (LRU) önbellek kullanır.
  • Görüntüleri verimli bir şekilde çözer.
  • Arka plan iş parçacığında bitmap'lerin değiştirilmesini destekler.
  • Basit çapraz geçişe sahiptir.
  • Görüntü yükleme ilerleme geri çağrısı var.

Klon DroidPartsGram bir örnek için:

Resim açıklamasını buraya girin


Merhaba, kod örnekleri bir göz vardı ama ben bir ArrayAdapter ile ImageFetcher kullanarak sorunları yaşıyorum, benim sorum bakarak olur? stackoverflow.com/questions/21089147/… Teşekkürler =]
masha

16

Tembel yükleme görüntüleri için hangi kütüphanenin kullanılacağı konusunda kararsız olan biri için hızlı bir ipucu:

Dört temel yol vardır.

  1. DIY => En iyi çözüm değil, birkaç görüntü için ve başka kütüphaneleri kullanma zahmeti olmadan gitmek istiyorsanız

  2. Volley'nin Tembel Yükleme kütüphanesi => Android çocuklar. Güzel ve her şey ama kötü belgelenmiş ve bu nedenle kullanmak için bir sorun.

  3. Picasso: Sadece işe yarayan basit bir çözüm, getirmek istediğiniz görüntü boyutunu bile belirtebilirsiniz. Kullanımı çok basittir, ancak çok sayıda görüntü ile uğraşmak zorunda olan uygulamalar için çok "performans" olmayabilir.

  4. UIL: Görüntüleri tembel olarak yüklemenin en iyi yolu. Görüntüleri önbelleğe alabilir (elbette izne ihtiyacınız vardır), yükleyiciyi bir kez başlatabilir, sonra işinizi yapabilirsiniz. Şimdiye kadar gördüğüm en olgun asenkron görüntü yükleme kütüphanesi.


15

Novoda ayrıca harika bir tembel resim yükleme kütüphanesine sahiptir ve Songkick, Podio, SecretDJ ve ImageSearch gibi birçok uygulama kütüphanelerini kullanır.

Kütüphaneleri burada Github'da barındırılıyor ve oldukça aktif bir sorun izleyicisine sahipler . Projeleri de oldukça aktif görünüyor, bu cevabı yazarken 300'den fazla taahhüt var.


1
Aslında Novoda harika bir kütüphane ama ... bazen büyük bir kütüphaneye ve çözümün basit bir yaklaşımına ihtiyacınız yok. Bu yüzden Github'daki LazyList çok iyi, eğer uygulamalarınız sadece listView'da bir görüntü gösteriyorsa ve uygulamanızın ana özelliği değilse, sadece daha hafif bir şey kullanmayı tercih edeceğim başka bir etkinlik. Aksi takdirde, sık kullanmanız gerekeceğini ve çekirdeğin bir parçası olduğunu biliyorsanız, Novoda'yı deneyin.
Nicolas Jafelle

13

LazyList çatalımı kontrol et . Temel olarak, ImageView çağrısını geciktirerek LazyList'i geliştiriyorum ve iki yöntem oluşturuyorum:

  1. "Resim yükleniyor ..." gibi bir şey koymanız gerektiğinde
  2. İndirilen resmi göstermeniz gerektiğinde.

Ben de bir uygulayarak ImageLoader geliştirilmiş singleton bu nesnede.


12

Shimmer düzenini Facebook gibi göstermek istiyorsanız bunun için resmi bir facebook kütüphanesi var. FaceBook Shimmer Android

Her şeyi halleder, sadece istediğiniz tasarım kodunu pırıltılı çerçeveye iç içe yerleştirmeniz gerekir. İşte bir örnek kod.

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

 <here will be your content to display />

</com.facebook.shimmer.ShimmerFrameLayout>

Ve işte bunun için java kodu.

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

Gradle dosyanıza bu bağımlılığı ekleyin.

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

İşte böyle görünüyor.Shimmer Android ekran görüntüsü


11

Yukarıdaki tüm kodlar kendi değer var ama benim kişisel deneyim ile sadece Picasso ile deneyin.

Picasso özellikle bu amaç için bir kütüphanedir, aslında önbelleği ve diğer tüm ağ işlemlerini otomatik olarak yönetecektir.Projenize kitaplık eklemeniz ve uzak URL'den resim yüklemek için tek bir kod satırı yazmanız gerekecektir.

Lütfen burayı ziyaret edin: http://code.tutsplus.com/tutorials/android-sdk-working-with-picasso--cms-22149


9

Kayma kitaplığını kullanın. Benim için çalıştı ve kodunuz için de çalışacak. Hem görüntüler hem de gifler için çalışır.

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

                @Override
                public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
                    return false;
                }
            })
            .into(imagePreview);
}

7

Bir cazibe gibi çalışan farklı bir yol önerebilirim: Android Sorgu.

Bunu indirebilirsiniz JAR dosyayı buraya

AQuery androidAQuery = new AQuery(this);

Örnek olarak:

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

Çok hızlı ve doğru ve bunu yüklerken animasyon, bitmap (gerekirse), vb. Gibi birçok özellik bulabilirsiniz.


7

Ver Aquery bir deneyin. Görüntüleri eşzamansız olarak yüklemek ve önbelleğe almak için inanılmaz basit yöntemlere sahiptir.



4
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

Bu sorunu yaşadım ve lruCache'i uyguladım. API 12 ve üstü sürümlere ihtiyacınız olduğunu veya uyumluluk v4 kütüphanesini kullandığınızı düşünüyorum. lurCache hızlı bir bellektir, ancak bir bütçesi de vardır, bu yüzden bir disk önbellek kullanabileceğinizden endişe ediyorsanız ... Hepsi Bitmap'leri Önbelleğe Alma'da açıklanır .

Şimdi böyle bir yerden çağırdığım tek bir uygulama olan uygulamanızı sağlayacağım :

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

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

Web görüntüsünü alırken bir bağdaştırıcının getView öğesinde önbelleğe almak ve ardından yukarıdaki kodu çağırmak için ideal kod şunlardır:

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);
        }
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.