एंड्रॉइड में लिस्ट व्यू में छवियों को कैसे लोड करें


1930

मैं ListViewउन छवियों से जुड़े कुछ चित्रों और कैप्शन को प्रदर्शित करने के लिए उपयोग कर रहा हूं । मुझे इंटरनेट से चित्र मिल रहे हैं। क्या आलसी लोड छवियों का एक तरीका है ताकि पाठ प्रदर्शित होने पर, यूआई अवरुद्ध न हो और चित्र डाउनलोड होते ही प्रदर्शित हो जाएं?

छवियों की कुल संख्या निश्चित नहीं है।


10
आप GreenDroid के AsyncImageView का उपयोग कर सकते हैं । बस बुलाओ setUrl
पास्कल दिमासिमो

7
मैंने इसका इस्तेमाल किया है। यह एक अद्भुत कार्यान्वयन है। बुरी खबर यह है कि AsyncImageView एक बड़ी GreenDroid परियोजना का एक हिस्सा है, जो आपके आवेदन को उस स्थिति में भी बड़ा बना देता है जब आपको सभी की आवश्यकता होती है AsyncImageView। इसके अलावा, लगता है, GreenDroid परियोजना 2011 के बाद से अपडेट नहीं की गई है।
बोरिसट्रस्ट

5
आप इस लाइब्रेरी को एक कोशिश भी दे सकते हैं: Android-http-image-manager जो मेरी राय में छवियों के अतुल्यकालिक लोडिंग के लिए सबसे अच्छा है।
रितेश कुमार दुबे

34
बस पिकासो का उपयोग करें, यह सब खुद करेगा। 'Picasso.with (yourContext) .load (img src / path / drawable here) .into (imageView यानी आपका लक्ष्य);) बस!
अनुज शर्मा

6
प्रयोग करके देखें: github.com/nostra13/Android-Universal-Image-Loader , यह लाइब्रेरी आलसी लोडिंग और इमेज कैशिंग के लिए बहुत तेज़ और कुशल है
krunal patel

जवाबों:


1086

यहां मैंने उन छवियों को रखने के लिए बनाया है जो वर्तमान में मेरा ऐप प्रदर्शित कर रहा है। कृपया ध्यान दें कि यहाँ उपयोग में आने वाली "लॉग" ऑब्जेक्ट एंड्रॉइड के अंदर अंतिम लॉग क्लास के आसपास मेरा कस्टम रैपर है।

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
मुझे लगता है कि आपको SoftReferences का उपयोग करना चाहिए ताकि आपका प्रोग्राम कभी भी OutOfMemoryException का कारण न बने। जब जीसी हीप को क्लीयर कर सकता है जब ढेर का आकार बढ़ रहा होता है ... आप अपनी खुद की पीढ़ी का प्रबंधन कर सकते हैं जैसे कि कुछ सेकंड के बाद आप अपनी छवियों को उस सूची में डाल सकते हैं और लोड करने से पहले आपको जांचना चाहिए कि यदि छवि मौजूद है तो इसे फिर से डाउनलोड न करें बल्कि इकट्ठा करें यह उस सूची से और आपकी सॉफ्ट सूची में वापस डाल रहा है और कुछ समय बाद आप अपनी हार्डलिस्ट को शुद्ध कर सकते हैं :)
AZ_


12
क्या आपको कोई वापसी याद आती है जब drawableMap में छवि होती है ... बिना भ्रूण-धागा शुरू किए?
करूसल

5
इस कोड में कई समस्याएं हैं। सबसे पहले आपको ड्राअवेबल्स को कैश करना चाहिए, जिससे मेमोरी लीक हो जाएगी: stackoverflow.com/questions/7648740/… । दूसरी बात यह है कि कैश को कभी साफ़ नहीं किया जाता है, इसलिए यह हमेशा के लिए बढ़ जाएगा, यह एक और मेमोरी लीक है।
satur9nine


1024

मैंने छवियों के साथ एक आलसी सूची (गिटहब में स्थित) का एक सरल डेमो बनाया ।

मूल उपयोग

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

अपने AndroidManifest.xml में निम्नलिखित अनुमतियां जोड़ना न भूलें:

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

ImageLoader का केवल एक उदाहरण बनाएं और इसे अपने एप्लिकेशन के चारों ओर पुनः उपयोग करें। इस तरह से इमेज कैशिंग अधिक कुशल होगी।

यह किसी के लिए मददगार हो सकता है। यह पृष्ठभूमि थ्रेड में छवियों को डाउनलोड करता है। छवियाँ एक एसडी कार्ड और मेमोरी में कैश की जा रही हैं। कैश कार्यान्वयन बहुत सरल है और डेमो के लिए पर्याप्त है। मैं मेमोरी की खपत को कम करने के लिए इनसाइप्लाइज़ के साथ छवियों को डीकोड करता हूं। मैं भी पुनर्नवीनीकरण विचारों को सही ढंग से संभालने की कोशिश करता हूं।

वैकल्पिक शब्द


7
धन्यवाद, मैं अपनी परियोजना में लगभग हर जगह आपके कोड के थोड़ा संशोधित संस्करण का उपयोग कर रहा हूं: code.google.com/p/vimeoid/source/browse/apk/src/com/fedorvlasov/…
shaman.sive

3
क्या किसी ने विकल्प के रूप में गिलेस डेब्यूने के कोड को देखा है। मेमोरी कैशिंग बनाम एसडी कार्ड और 2) में जो दो बड़े अंतर मुझे दिखाई देते हैं वे हैं 1) थ्रेड पूल के बजाय AsyncTasks का उपयोग। Android-developers.blogspot.com/2010/07/…
रिचर्ड

4
एक बग है, कभी-कभी इसे निकाल दिया जाता है: 10-13 09: 58: 46.738: ERROR / AndroidRuntime (24250): अनकैप्ड हैंडलर: थ्रेड एक्साइटिंग एक्सट्रीम अपवाद के कारण 10-13 09: 58: 46.768, ERROR / AndroidRuntime (24250) : java.lang.ArrayIndexOutOfBoundsException: Array सूचकांक सीमा से बाहर: 0 10-13 09: 58: 46.768: ERROR / AndroidRuntime (24250): java.util.Vector.elementAt (वेक्टर.java:331) 10-13 09 पर: 58: 46.768: ERROR / AndroidRuntime (24250): java.util.Vector.get (वेक्टर.java:445) 10-13 09: 58: 46.768: ERROR / AndroidRuntime (24250): com.my.app.image पर .ImageLoader $ PhotosQueue.Clean (ImageLoader.java:91)
मिकोसोस

64
मैं मेरे जैसे नए लोगों के लिए जोड़ना चाहूंगा कि यदि आप इस कोड को अपने स्वयं के प्रोजेक्ट में जोड़ना चाहते हैं, तो आपको मैनिफ़ेस्ट में बाह्य कैश अनुमतियाँ जोड़ना होगा। धन्यवाद
एडम

2
@BruceHill नवीनतम स्रोत कोड में कोई फोटो क्यू नहीं है। आप कुछ बहुत पुराने संस्करण का उपयोग कर रहे हैं।
फेडर

551

मैं ओपन सोर्स इंस्ट्रूमेंट यूनिवर्सल इमेज लोडर की सलाह देता हूं । यह मूल रूप से Fedor Vlasov के प्रोजेक्ट LazyList पर आधारित है और तब से इसमें काफी सुधार किया गया है।

  • मल्टीथ्रेड छवि लोड हो रहा है
  • चौड़ी ट्यूनिंग की व्यापकता ImageLoader का विन्यास (थ्रेड एग्ज़ॅक्टर, डाउनलोडर, डिकोडर, मेमोरी और डिस्क कैश, डिस्प्ले इमेज ऑप्शंस, और अन्य)
  • मेमोरी और / या डिवाइस की फाइल sysytem (या एसडी कार्ड) पर इमेज कैशिंग की संभावना
  • लोड करने की प्रक्रिया को "सुनने" की संभावना
  • अलग-अलग विकल्पों के साथ हर डिस्प्ले इमेज कॉल को कस्टमाइज़ करने की संभावना
  • विजेट समर्थन
  • Android 2.0+ समर्थन


16
यदि आप महान "इमेज लोडिंग" कोड की तलाश कर रहे हैं, जो इसके निर्माता अपने अनमोल बच्चे (न केवल एक समय के समाधान) के रूप में मानता है और बनाए रखता है, तो यू ने इसे पाया; बड़े अप्स नोस्ट्रा
AndroidGecko

वास्तव में बहुत अच्छा काम है, लेकिन यह मेरी सूची में थोड़ा सा पिछड़ जाता है। यदि आप सर्वश्रेष्ठ प्रदर्शन 'ImageLoader' का निर्माण कर सकते हैं ... या शायद इसलिए कि 'DisplayImageOptions'।
दिनेगो

मुझे यह ग्रिडव्यू बहुत पसंद है लेकिन मैं इसे अपने ट्यूटोरियल के लिए उपयोग नहीं कर सकता। मैं Android का एक शुरुआती हूँ। मैं ग्रिडव्यू के बारे में आवेदन करता हूं, लेकिन मेरा आवेदन 15 था, इसलिए मुझे पृष्ठभूमि थ्रेड में प्रक्रिया के लिए एसिंक्टस्क का उपयोग करने की आवश्यकता थी। मैं इस ग्रिडव्यू का उपयोग करता था लेकिन यह काम नहीं करता है। मैं इसका उपयोग कैसे कर सकता हूँ targetSdkVersion 15?
kongkea

आप टैग [यूनिवर्सल-इमेज-लोडर]
nostra13

3
आधिकारिक एंड्रॉइड डॉक्स को पढ़ने और इस सामान को स्वयं करने की कोशिश करने के बाद, मुझे पूरा यकीन है कि यह लाइब्रेरी अंत में सभी छवि लोड हो रही है। पर्याप्त नहीं बढ़ा सकते।
कोर

158

प्रदर्शन के लिए मल्टीथ्रेडिंग , गाइल्स डेब्यूने द्वारा एक ट्यूटोरियल।

यह एंड्रॉइड डेवलपर्स ब्लॉग से है। सुझाया गया कोड उपयोग करता है:

  • AsyncTasks
  • एक कठिन, सीमित आकार FIFO cache,।
  • एक नरम, आसानी से garbage collectकैश।
  • डाउनलोड करते समय एक प्लेसहोल्डर Drawable

यहां छवि विवरण दर्ज करें


10
यह 2.1 में भी ठीक काम करता है। बस AndroidHttpClient का उपयोग न करें।
थॉमस अहले

2
@ thomas-ahle धन्यवाद, मैंने देखा कि AndroidHttpClient 2.1 में त्रुटियां दे रहा था, क्योंकि यह 2.2 से लागू है, लेकिन वास्तव में इसे बदलने के लिए कुछ और खोजने की कोशिश नहीं की।
एडिनिया

4
@ एडिना तुम सही हो, मैं भूल गया। हालाँकि इस रेसिपी में ऐसा कुछ भी नहीं है जो सिर्फ एक सामान्य HttpClient के साथ नहीं किया जा सकता है।
थॉमस अहले

मैंने कई स्थानों पर सुना है, कि Google नरम संदर्भों की अनुशंसा नहीं करता है, क्योंकि एंड्रॉइड कर्नेल सिस्टम के पुराने संस्करणों की तुलना में इन संदर्भों को इकट्ठा करने के लिए बहुत उत्सुक है।
मुहम्मद अहमद अबूतालिब

108

अद्यतन: ध्यान दें कि यह उत्तर अब बहुत अप्रभावी है। गारबेज कलेक्टर सॉफ्टरफेर और वीइकरेफेरेंस पर आक्रामक रूप से कार्य करता है, इसलिए यह कोड नए ऐप्स के लिए उपयुक्त नहीं है। (इसके बजाय, अन्य उत्तर में सुझाए गए यूनिवर्सल इमेज लोडर जैसे पुस्तकालयों का प्रयास करें ।)

कोड के लिए जेम्स का धन्यवाद, और सॉफ्टरेंस का उपयोग करने के सुझाव के लिए बाओ-लांग। मैंने जेम्स के कोड पर सॉफ्टरफेर बदलाव लागू किया। दुर्भाग्य से सॉफ्टराइफ़र्स ने मेरी छवियों को कचरा एकत्र करने का कारण बना दिया। मेरे मामले में यह SoftReference सामान के बिना ठीक था, क्योंकि मेरी सूची का आकार सीमित है और मेरी छवियां छोटी हैं।

Google समूहों पर SoftReferences के बारे में एक साल पहले से एक चर्चा है: थ्रेड के लिए लिंक । बहुत जल्दी कचरा संग्रहण के समाधान के रूप में, वे मैन्युअल रूप से VM ढेर आकार का उपयोग करके dalvik.system.VMRuntime.setMinimumHeapSize () का उपयोग करने की संभावना का सुझाव देते हैं, जो मेरे लिए बहुत आकर्षक नहीं है।

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
आप हार्ड-जेनरेशन और सॉफ्टनररेशन जैसी पीढ़ियों का निर्माण कर सकते हैं। आप एक समय को ठीक कर सकते हैं कैश 3 सेकंड में एक्सेस नहीं की गई सभी छवियों को साफ़ कर देगा .. आप Google अलमारियों पर एक नज़र रख सकते हैं
AZ_

developer.android.com/reference/java/lang/ref/… सॉफ्टरेंस डॉक में कैशिंग के बारे में एक नोट है, "कैशिंग के लिए शीतल संदर्भों से बचें" अनुभाग देखें। अधिकांश अनुप्रयोगों को नरम संदर्भों के बजाय android.util.LruCache का उपयोग करना चाहिए।
वोकिलम

मैं आपके कोड की प्रशंसा करता हूं लेकिन अब नए एंड्रॉइड O / S में 'आक्रामक' कचरा एकत्र करना है। कमजोर संदर्भ रखने से मुझे कोई मतलब नहीं है।
j2emanue

@ j2emanue आप सही हैं, जैसा कि मैंने अपने उत्तर के शीर्ष पर इंगित करने का प्रयास किया, सॉफ्टराइफ़र्स बहुत जल्दी एकत्रित कचरा हैं। मैं इस उत्तर को संपादित करने की कोशिश करूंगा ताकि यह और भी स्पष्ट हो सके।
TalkLittle

96

पिकासो

जेक व्हार्टन की पिकासो लाइब्रेरी का उपयोग करें। (ए पर्फेक्ट इमेज लाईडिंग लाइब्रेरी एक्शनबर्करलॉक के डेवलपर के रूप में)

एंड्रॉइड के लिए एक शक्तिशाली छवि डाउनलोडिंग और कैशिंग लाइब्रेरी।

छवियां एंड्रॉइड एप्लिकेशन में बहुत आवश्यक संदर्भ और दृश्य स्वभाव जोड़ती हैं। पिकासो आपके एप्लिकेशन में परेशानी मुक्त छवि लोड करने की अनुमति देता है - अक्सर कोड की एक पंक्ति में!

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

Android पर छवि लोड करने के कई सामान्य नुकसान स्वचालित रूप से पिकासो द्वारा नियंत्रित किए जाते हैं:

ImageView रीसाइक्लिंग को संभालना और एडॉप्टर में रद्दीकरण डाउनलोड करना। न्यूनतम स्मृति उपयोग के साथ जटिल छवि परिवर्तन। स्वचालित मेमोरी और डिस्क कैशिंग।

पिकासो जेक व्हार्टन की लाइब्रेरी

फिसलन

ग्लाइड एंड्रॉइड के लिए एक तेज और कुशल ओपन सोर्स मीडिया प्रबंधन ढांचा है जो मीडिया डिकोडिंग, मेमोरी और डिस्क कैशिंग और संसाधन पूलिंग को एक सरल और आसान इंटरफ़ेस का उपयोग करता है।

ग्लाइड वीडियो स्टॉक्स, इमेज और एनिमेटेड जीआईएफ को लाने, डिकोड करने और प्रदर्शित करने का समर्थन करता है। ग्लाइड में एक लचीली एपी शामिल है जो डेवलपर्स को लगभग किसी भी नेटवर्क स्टैक में प्लग करने की अनुमति देता है। डिफ़ॉल्ट रूप से ग्लाइड एक कस्टम HttpUrlConnection आधारित स्टैक का उपयोग करता है, लेकिन इसमें Google के वॉली प्रोजेक्ट या स्क्वायर के OkHttp लाइब्रेरी के बजाय उपयोगिता लाइब्रेरी प्लग भी शामिल है।

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

ग्लाइड का प्राथमिक ध्यान किसी भी प्रकार की छवियों की सूची को जितना संभव हो उतना सुचारू और तेज़ बनाना है, लेकिन ग्लाइड लगभग किसी भी मामले के लिए प्रभावी है जहाँ आपको दूरस्थ छवि प्राप्त करने, आकार बदलने और प्रदर्शित करने की आवश्यकता होती है।

ग्लाइड इमेज लोडिंग लाइब्रेरी

फ़्रेस्को फेसबुक द्वारा

फ्रेस्को Android अनुप्रयोगों में छवियों को प्रदर्शित करने के लिए एक शक्तिशाली प्रणाली है।

फ्रेस्को छवि लोड करने और प्रदर्शन का ख्याल रखता है, इसलिए आपको नहीं करना है। यह नेटवर्क, स्थानीय भंडारण या स्थानीय संसाधनों से छवियों को लोड करेगा, और एक प्लेसहोल्डर को प्रदर्शित करेगा जब तक कि छवि नहीं आ गई है। इसमें कैश के दो स्तर हैं; एक मेमोरी में और दूसरा इंटरनल स्टोरेज में।

फ्रेस्को गितुब

एंड्रॉइड 4.x और निचले हिस्से में, फ्रेस्को एंड्रॉइड मेमोरी के एक विशेष क्षेत्र में छवियां डालता है। यह आपके एप्लिकेशन को तेज़ी से चलाने देता है - और बहुत कम बार भयानक DOOMemoryError को पीड़ित करता है।

फ्रेस्को प्रलेखन


पिकासो स्क्वायर द्वारा विकसित एक पुस्तकालय है
लॉर्डरेडेनकेके

82

उच्च प्रदर्शन लोडर - यहाँ दिए गए तरीकों की जांच करने के बाद, मैंने कुछ बदलावों के साथ बेन के समाधान का उपयोग किया -

  1. मैंने महसूस किया कि ड्रॉबल्स के साथ काम करना तेज है, इसलिए बिटमैप्स के साथ मैं इसके बजाय ड्रॉबल्स का उपयोग करता हूं

  2. SoftReference का उपयोग करना बहुत अच्छा है, लेकिन यह कैश्ड छवि को बहुत बार डिलीट करने के लिए बनाता है, इसलिए मैंने एक लिंक्ड लिस्ट जोड़ी, जो इमेज रेफरेंस रखती है, इमेज को डिलीट करने से रोकती है, जब तक कि यह पूर्वनिर्धारित आकार तक नहीं पहुंच जाती है

  3. इनपुटस्ट्रीम खोलने के लिए मैंने java.net.URLConnection का उपयोग किया जो मुझे वेब कैश का उपयोग करने की अनुमति देता है (आपको पहले एक प्रतिक्रिया कैश सेट करने की आवश्यकता है, लेकिन यह एक और कहानी है)

मेरा कोड:

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

बहुत अच्छा काम करता है! BTW वहाँ वर्ग के नाम में एक टाइपो है।
मुलिन्स

5
मामले में यह किसी और को समय बचाता है: 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;
माइकल रीड

बहुत बहुत धन्यवाद, यह एक अच्छा कार्यान्वयन है। मैंने एक अलग प्लेसहोल्डर भी रखा है जब ड्रॉबल लोड किया जा रहा है ताकि उपयोगकर्ता को कुछ प्रतिक्रिया मिल सके।
जुआन हर्नांडेज़

इसके अलावा, मुझे लगता है कि एफआईएफओ डिफ़ॉल्ट एफआईएफओ के बजाय निष्पादनकर्ता सेवा (mThreadPool) में एक LIFO कतार का उपयोग करना बेहतर है, इसलिए अंतिम अनुरोध किए गए चित्र (जो संभवतः दृश्यमान हैं) पहले लोड किए गए हैं। देखें stackoverflow.com/questions/4620061/how-to-create-lifo-executor
जुआन हर्नांडेज़

9
@MichaelReed, यदि आप एक ग्रहण उपयोगकर्ता हैं, तो मैं Ctrl-Shift-O (यह अक्षर O, संख्या 0 नहीं) का उपयोग करने की सलाह देता हूं। यह आयात को जोड़ने की प्रक्रिया को स्वचालित करता है और उन्हें आपके लिए व्यवस्थित करता है। यदि आप Mac पर हैं, तो इसके बजाय Command-Shift-O का उपयोग करें।
सिलिथक्रोव

78

मैंने इस Android प्रशिक्षण का पालन किया है और मुझे लगता है कि यह मुख्य UI को अवरुद्ध किए बिना छवियों को डाउनलोड करने में एक उत्कृष्ट काम करता है। यह कैशिंग और कई छवियों के माध्यम से स्क्रॉलिंग से निपटने का काम भी करता है: बड़े बिटमैप को कुशलतापूर्वक लोड करना


मुझे क्षमा करें, मैंने केवल Google IO ऐप के लिए एकल वर्ग को इंगित किया है (और मुझे संपादित करने में बहुत देर हो गई है)। आपको वास्तव में उनकी सभी छवि लोडिंग और कैशिंग उपयोगिता कक्षाओं का अध्ययन करना चाहिए जो आप कैश क्लास के समान पैकेज में पा सकते हैं ।
एमकेयू

किसी को भी देखने के लिए छवि लोड करने / कैशिंग से निपटने में मदद करने के लिए iosched एप्लिकेशन के उपयोग फ़ोल्डर से DiskLruCache, छवि * .java फ़ाइलों को हथियाने की सिफारिश करेंगे? मेरा मतलब है कि यह निश्चित रूप से इस विषय पर ऑनलाइन डेवलपर गाइड का पालन करने के लायक है, लेकिन इन वर्गों (iosched से) पैटर्न के साथ थोड़ा आगे जाते हैं।
गौतम

65

1. पिकासो आपके एप्लिकेशन में परेशानी मुक्त छवि लोड करने की अनुमति देता है — अक्सर कोड की एक पंक्ति में!

ग्रेडेल का उपयोग करें:

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

कोड की सिर्फ एक पंक्ति!

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

2. सरकना Android के लिए एक छवि लोड हो रहा है और कैशिंग पुस्तकालय चिकनी स्क्रॉल पर ध्यान केंद्रित किया

ग्रेडेल का उपयोग करें:

repositories {
  mavenCentral() 
  google()
}

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

// एक साधारण दृश्य के लिए:

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

3. फ्रेस्को एंड्रॉइड एप्लिकेशन में छवियों को प्रदर्शित करने के लिए एक शक्तिशाली प्रणाली है फ़्रेस्को छवि लोडिंग और डिस्प्ले का ध्यान रखता है, इसलिए आपको ऐसा करने की आवश्यकता नहीं है।

फ्रेस्को के साथ शुरुआत करना


यह ट्यूटोरियल आपको PICASOO के लिए और अधिक मदद कर सकता है: - androidtutorialshub.com/… और GLIDE: - androidtutorialshub.com/…
lalit vasan

52

मैंने एक ट्यूटोरियल लिखा है जो बताता है कि एक सूची में छवियों के आलसी-लोडिंग कैसे करें। मैं पुनरावर्तन और संगामिति के मुद्दों के बारे में कुछ विस्तार से जाना। मैं बहुत सारे धागे को रोकने के लिए एक निश्चित थ्रेड पूल का उपयोग करता हूं।

सूची ट्यूटोरियल में छवियों का आलसी लोडिंग


41

जिस तरह से मैं करता हूं वह पृष्ठभूमि में छवियों को डाउनलोड करने और प्रत्येक सूची आइटम के लिए कॉलबैक को सौंपने के लिए एक धागा लॉन्च करके है। जब कोई छवि समाप्त हो जाती है तो इसे डाउनलोड करने पर कॉलबैक होता है जो सूची आइटम के लिए दृश्य को अपडेट करता है।

जब आप विचारों को पुन: चक्रित कर रहे हों तो यह विधि बहुत अच्छी तरह से काम नहीं करती है।


प्रत्येक छवि के लिए एक थ्रेड का उपयोग करना वह दृष्टिकोण है जो मैं भी उपयोग करता हूं। यदि आप अपने मॉडल को अपने दृष्टिकोण से अलग करते हैं, तो आप उन्हें कैश्ड रखने के लिए गतिविधि के बाहर के मॉडल (जैसे आपके 'एप्लिकेशन' क्लास में) को जारी रख सकते हैं। यदि आपके पास कई छवियां हैं, तो संसाधनों से बाहर निकलने से सावधान रहें।
जेम्स ए विल्सन

क्या आप विस्तृत कर सकते हैं मैं Android विकास के लिए नया हूँ। यद्यपि सुझावों के लिए धन्यवाद
खोया हुआ

14
प्रत्येक छवि के लिए एक नया सूत्र शुरू करना एक प्रभावी समाधान नहीं है। आप बहुत सारे थ्रेड को मेमोरी और फ्रीज़िंग यूआई में समाप्त कर सकते हैं।
फेडर

फेडोर, सहमत, मैं आमतौर पर एक कतार और एक थ्रेड पूल का उपयोग करता हूं, यही imo जाने का सबसे अच्छा तरीका है।
जसोन्धुअन

32

मैं सिर्फ एक और अच्छा उदाहरण जोड़ना चाहता हूं, एक्सएमएल एडेप्टर । जैसा कि यह Google द्वारा उपयोग किया जाता है और मैं OutOfMemory त्रुटि से बचने के लिए उसी तर्क का उपयोग कर रहा हूं।

मूल रूप से यह ImageDownloader आपका उत्तर है (क्योंकि यह आपकी अधिकांश आवश्यकताओं को कवर करता है)। कुछ आप उसमें भी लागू कर सकते हैं।


2
ImageDownloader वर्ग का अनुपालन नहीं: नीचे हल देखने code.google.com/p/parleys-android-nextgen/issues/detail?id=1
सैम

29

यह एंड्रॉइड पर एक आम समस्या है जिसे कई लोगों द्वारा कई तरीकों से हल किया गया है। मेरी राय में मैंने देखा सबसे अच्छा समाधान पिकासो नामक अपेक्षाकृत नया पुस्तकालय है । यहाँ पर प्रकाश डाला गया है:

  • ओपन सोर्स, लेकिन द्वारा अध्यक्षता Jake Whartonकी ActionBarSherlock प्रसिद्धि।
  • कोड की एक पंक्ति के साथ नेटवर्क या ऐप संसाधनों से अतुल्यकालिक रूप से छवियों को लोड करें
  • स्वचालित ListViewपहचान
  • स्वचालित डिस्क और मेमोरी कैशिंग
  • कस्टम परिवर्तन कर सकते हैं
  • विन्यास विकल्प के बहुत सारे
  • सुपर सरल एपीआई
  • बार-बार अपडेट किया गया

29

मैं नए एंड्रॉइड वॉली लाइब्रेरी से NetworkImageView का उपयोग कर रहा हूं com.android.volley.toolbox.NetworkImageView, और यह बहुत अच्छा काम कर रहा है। जाहिर है, यह वही दृश्य है जो Google Play और अन्य नए Google अनुप्रयोगों में उपयोग किया जाता है । निश्चित रूप से जाँच के लायक है।


1
मुझे लगता है कि यह सबसे अच्छा समाधान है - अन्य उत्तर बहुत पुराने हैं - वॉली वास्तव में तेज़ है और जेक वॉर्थन डिस्कल्यूशैच के साथ संयुक्त रूप से इसका एक बढ़िया समाधान है - मैंने दूसरों की बहुत कोशिश की, लेकिन वॉली के रूप में कोई भी स्थिर और तेज़ नहीं है
अलेक्जेंडर सिदिकोव फाफ

26

खैर, इंटरनेट से इमेज लोडिंग समय के कई समाधान हैं। आप लाइब्रेरी एंड्रॉइड-क्वेरी का उपयोग भी कर सकते हैं । यह आपको सभी आवश्यक गतिविधि देगा। सुनिश्चित करें कि आप क्या करना चाहते हैं और लाइब्रेरी विकी पेज को पढ़ना चाहते हैं। और इमेज लोडिंग प्रतिबंध को हल करें।

यह मेरा कोड है:

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

यह आपकी आलसी लोडिंग समस्या को हल करना चाहिए।


मेरे लिए अच्छा काम है, लेकिन अपनी परियोजना में शामिल करने के लिए जार फ़ाइल की आवश्यकता है। आप उस JAR फ़ाइल को यहाँ से डाउनलोड कर सकते हैं AQuery androidAQuery = new AQuery (यह); लिंक है: code.google.com/archive/p/android-query/downloads
सेलिम रज़ा

25

मुझे लगता है कि यह मुद्दा एंड्रॉइड डेवलपर्स के बीच बहुत लोकप्रिय है, और ऐसे बहुत सारे पुस्तकालय हैं जो इस मुद्दे को हल करने का दावा करते हैं, लेकिन उनमें से कुछ ही निशान पर लगते हैं। AQuery ऐसा ही एक पुस्तकालय है, लेकिन यह सभी पहलुओं में से अधिकांश से बेहतर है और इसके लिए प्रयास करने योग्य है।


22

आपको यह कोशिश करनी चाहिए कि यह यूनिवर्सल लोडर सबसे अच्छा है। मैं आलसी लोडिंग पर कई आरएनडी करने के बाद इसका उपयोग कर रहा हूं।

यूनिवर्सल इमेज लोडर

विशेषताएं

  • मल्टीथ्रेड छवि लोड हो रहा है (async या सिंक)
  • ImageLoader के कॉन्फ़िगरेशन (थ्रेड एक्ज़ीक्यूटर्स, डाउनलोडर, डिकोडर, मेमोरी और डिस्क कैश, डिस्प्ले इमेज ऑप्शन, आदि) का व्यापक अनुकूलन।
  • हर प्रदर्शन छवि कॉल के लिए कई अनुकूलन विकल्प (स्टब चित्र, कैशिंग स्विच, डिकोडिंग विकल्प, बिटमैप प्रसंस्करण और प्रदर्शित करना, आदि)
  • मेमोरी और / या डिस्क पर डिवाइस कैशिंग (डिवाइस की फ़ाइल प्रणाली या एसडी कार्ड)
  • लोडिंग प्रक्रिया सुनना (डाउनलोड प्रगति सहित)

Android 2.0+ समर्थन

यहां छवि विवरण दर्ज करें


20

शटरबग पर एक नजर , Applidium के लाइटवेट SDWebImage (iOS पर एक अच्छी लाइब्रेरी) पोर्ट पर । यह एसिंक्रोनस कैशिंग का समर्थन करता है, विफल URL को संग्रहीत करता है, समरूपता को अच्छी तरह से संभालता है, और सहायक उपवर्ग शामिल हैं।

पुल अनुरोध (और बग रिपोर्ट) का भी स्वागत है!


16

DroidParts में ImageFetcher है जिसे आरंभ करने के लिए शून्य कॉन्फ़िगरेशन की आवश्यकता होती है।

  • हाल ही में प्रयुक्त एक डिस्क और इन-मेमोरी लिस्ट का उपयोग करता है (LRU) कैश।
  • कुशलता से छवियों को डीकोड करता है।
  • पृष्ठभूमि थ्रेड में बिटमैप को संशोधित करने का समर्थन करता है।
  • सरल क्रॉस-फीका है।
  • इमेज लोडिंग प्रगति कॉलबैक है।

एक उदाहरण के लिए क्लोन DroidPartsGram :

यहां छवि विवरण दर्ज करें


नमस्ते, मैं कोड उदाहरण पर एक नज़र है, लेकिन मैं एक ArrayAdapter के साथ ImageFetcher का उपयोग कर मुद्दों कर रहा हूँ, तुम मेरे सवाल को देख मन होता है? stackoverflow.com/questions/21089147/… धन्यवाद =]
माशा

16

किसी ऐसे व्यक्ति के लिए बस एक त्वरित टिप, जो आलसी-लोडिंग छवियों के लिए लाइब्रेरी का उपयोग करने के बारे में अनिर्णय में है:

चार बुनियादी तरीके हैं।

  1. DIY => सबसे अच्छा समाधान नहीं है लेकिन कुछ छवियों के लिए और यदि आप दूसरों के पुस्तकालयों का उपयोग करने की परेशानी के बिना जाना चाहते हैं

  2. वॉली के आलसी लोडिंग लाइब्रेरी => Android पर लोगों से। यह अच्छा है और सब कुछ लेकिन खराब तरीके से प्रलेखित है और इसलिए उपयोग करने में समस्या है।

  3. पिकासो: एक सरल समाधान जो बस काम करता है, आप उस सटीक छवि आकार को भी निर्दिष्ट कर सकते हैं जिसे आप लाना चाहते हैं। यह उपयोग करने के लिए बहुत सरल है, लेकिन उन ऐप्स के लिए बहुत "निष्पादन योग्य" नहीं हो सकता है जिन्हें नम्र मात्रा में छवियों से निपटना पड़ता है।

  4. यूआईएल: आलसी लोड छवियों का सबसे अच्छा तरीका है। आप छवियों को कैश कर सकते हैं (आपको पाठ्यक्रम की अनुमति की आवश्यकता है), लोडर को एक बार प्रारंभ करें, फिर अपना काम करें। सबसे परिपक्व अतुल्यकालिक छवि लोडिंग लाइब्रेरी जो मैंने अब तक देखी है।


15

नोवोडा में एक शानदार आलसी इमेज लोडिंग लाइब्रेरी भी है और कई ऐप जैसे सोंगकिक, पोडियो, सीक्रेटडीजे और इमेज सर्च अपने पुस्तकालय का उपयोग करते हैं।

उनके पुस्तकालय को जीथब पर यहां होस्ट किया गया है और उनके पास एक बहुत सक्रिय मुद्दे ट्रैकर भी हैं। उनका प्रोजेक्ट काफी सक्रिय भी लगता है, इस उत्तर को लिखने के समय 300+ से अधिक के साथ।


1
वास्तव में नोवोडा एक महान पुस्तकालय है लेकिन ... कभी-कभी आपको एक विशाल पुस्तकालय और केवल समाधान के एक सरल दृष्टिकोण की आवश्यकता नहीं होती है। यही कारण है कि Github में LazyList इतना अच्छा है, अगर आपके ऐप केवल एक सूची दृश्य में एक छवि दिखाते हैं और आपके ऐप की मुख्य विशेषता नहीं है, तो बस एक और गतिविधि मैं कुछ हल्का उपयोग करना पसंद करूंगा। अन्यथा यदि आप जानते हैं कि आपको अक्सर उपयोग करना होगा और कोर का हिस्सा है, तो नोवोडा का प्रयास करें।
निकोलस जाफेल

13

LazyList के मेरे कांटे की जाँच करें । मूल रूप से, मैं ImageView की कॉल में देरी करके और दो तरीके बनाकर LazyList को बेहतर बनाता हूं:

  1. जब आपको "लोड हो रही छवि ..." जैसी कोई चीज़ डालनी हो
  2. जब आपको डाउनलोड की गई छवि दिखाने की आवश्यकता हो।

मैंने इस ऑब्जेक्ट में एक सिंगलटन को लागू करके ImageLoader में सुधार किया ।


12

यदि आप फेसबुक की तरह शिमर लेआउट प्रदर्शित करना चाहते हैं तो उसके लिए एक आधिकारिक फेसबुक लाइब्रेरी है। फेसबुक शिमर एंड्रॉइड

यह सब कुछ का ख्याल रखता है, आपको बस अपने वांछित डिज़ाइन कोड को झिलमिलाते फ्रेम में नेस्टेड तरीके से रखना होगा। यहाँ एक नमूना कोड है।

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

और यहाँ इसके लिए जावा कोड है।

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

अपनी निर्भरता फ़ाइल में इस निर्भरता को जोड़ें।

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

यहाँ है कि यह कैसा दिखता है।शिमर Android स्क्रीनशॉट


11

उपरोक्त सभी कोडों का अपना मूल्य है, लेकिन मेरे व्यक्तिगत अनुभव के साथ पिकासो के साथ बस कोशिश करें।

पिकासो इस उद्देश्य के लिए विशेष रूप से एक पुस्तकालय है, वास्तव में यह कैश और अन्य सभी नेटवर्क संचालन को स्वचालित रूप से प्रबंधित करेगा। आपको अपनी परियोजना में पुस्तकालय जोड़ना होगा और दूरस्थ URL से छवि को लोड करने के लिए कोड की एक पंक्ति लिखनी होगी।

कृपया यहाँ देखें: http://code.tutsplus.com/tutorials/android-sdk-working-with-picasso--cms-22149


9

ग्लाइड लाइब्रेरी का उपयोग करें। यह मेरे लिए काम करता है और आपके कोड के लिए भी काम करेगा। यह दोनों चित्रों के साथ-साथ जीआईएफ के लिए भी काम करता है।

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

मैं एक अलग तरीके की सिफारिश कर सकता हूं जो एक आकर्षण की तरह काम करता है: एंड्रॉइड क्वेरी।

आप यहाँ से उस JAR फ़ाइल को डाउनलोड कर सकते हैं

AQuery androidAQuery = new AQuery(this);

उदहारण के लिए:

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

यह बहुत तेज़ और सटीक है, और इसके उपयोग से आप एनीमेशन जैसी कई और सुविधाएँ पा सकते हैं जब लोड करना, बिटमैप प्राप्त करना (यदि आवश्यक हो), आदि।


7

दे दो Aquery एक कोशिश। इसमें एसिंक्रोनस रूप से छवियों को लोड करने और कैश करने के लिए आश्चर्यजनक सरल तरीके हैं।



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

मेरे पास यह मुद्दा था और lruCache को लागू किया। मेरा मानना ​​है कि आपको एपीआई 12 और उससे ऊपर के वीपीएन की जरूरत है या फिर वी 4 भाई लाइब्रेरी का इस्तेमाल करना चाहिए। LurCache तेज़ मेमोरी है, लेकिन इसका एक बजट भी है, इसलिए यदि आप इस बारे में चिंतित हैं कि आप एक डिस्ककैश का उपयोग कर सकते हैं ... यह सब कैशिंग बिटमैप्स में वर्णित है

अब मैं अपना कार्यान्वयन प्रदान करूंगा जो एक सिंगलटन है जिसे मैं इस तरह से कहीं से भी कॉल करूंगा:

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

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

यहां कैश के लिए आदर्श कोड है और फिर वेब इमेज को पुनर्प्राप्त करते समय एक एडॉप्टर के getView में ऊपर कॉल करें:

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);
        }
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.