Câu hỏi Tải hình ảnh kém trong ListView


Tôi đang sử dụng ListView để hiển thị một số hình ảnh và chú thích được liên kết với những hình ảnh đó. Tôi nhận được hình ảnh từ Internet. Có cách nào để tải hình ảnh xuống trong khi văn bản hiển thị, giao diện người dùng không bị khóa và hình ảnh được hiển thị khi chúng được tải xuống không?

Tổng số hình ảnh không cố định.


1733
2018-02-12 15:59


gốc


Bạn có thể dùng AsyncImageView của GreenDroid. Chỉ cần gọi setUrl. - Pascal Dimassimo
Tôi đã sử dụng nó. Đó là một triển khai tuyệt vời. Tin xấu là AsyncImageView là một phần của dự án GreenDroid lớn, làm cho ứng dụng của bạn lớn hơn ngay cả trong trường hợp tất cả những gì bạn cần là AsyncImageView. Ngoài ra, có vẻ như, dự án GreenDroid không được cập nhật kể từ năm 2011. - borisstr
Bạn thậm chí có thể thử thư viện này: Trình quản lý Android-http-image theo ý kiến ​​của tôi là tốt nhất cho tải hình ảnh không đồng bộ. - Ritesh Kumar Dubey
Chỉ cần sử dụng Picasso, nó sẽ tự làm tất cả. 'Picasso.with (yourContext) .load (img src / path / drawable here) .into (imageView tức là mục tiêu của bạn);' Đó là nó! - Anuj Sharma
thử sử dụng:github.com/nostra13/Android-Universal-Image-Loader , thư viện này rất nhanh và hiệu quả để tải chậm và lưu trữ hình ảnh - krunal patel


Các câu trả lời:


Dưới đây là những gì tôi đã tạo để giữ hình ảnh mà ứng dụng của tôi hiện đang hiển thị. Xin lưu ý rằng đối tượng "Đăng nhập" được sử dụng ở đây là trình bao bọc tùy chỉnh của tôi xung quanh lớp Đăng nhập cuối cùng bên trong Android.

package com.wilson.android.library;

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

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

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

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

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

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

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


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

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

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

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

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

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

1017
2018-02-18 03:56



Tôi nghĩ bạn nên sử dụng SoftReferences để chương trình của bạn sẽ không bao giờ gây ra OutOfMemoryException. Vì GC có thể xóa các yêu cầu mềm khi kích thước heap tăng ... bạn có thể quản lý thế hệ của riêng mình như sau vài giây, bạn có thể đưa hình ảnh vào danh sách đó và trước khi tải, bạn nên kiểm tra xem hình ảnh có tồn tại không. nó từ danh sách đó và cũng đưa nó trở lại danh sách softref của bạn và sau khi đôi khi bạn có thể thanh lọc danh sách cứng của bạn :) - AZ_
Dự án Google Shelves là một ví dụ tuyệt vời về cách họ đã làm code.google.com/p/shelves - AZ_
Bạn không bỏ lỡ một sự trở lại khi drawableMap chứa hình ảnh ... mà không bắt đầu tìm nạp-thread? - Karussell
Mã này có một số vấn đề. Trước tiên, bạn nên lưu vào bộ nhớ cache Drawables, điều này sẽ gây ra rò rỉ bộ nhớ: stackoverflow.com/questions/7648740/… . Thứ hai, chính bộ nhớ cache sẽ không bao giờ bị xóa để nó sẽ phát triển mãi mãi, đó là một sự rò rỉ bộ nhớ khác. - satur9nine
không ai nghe nói về LRU Cache  developer.android.com/training/displaying-bitmaps/… - Muhammad Babar


tôi đã làm một bản demo đơn giản về danh sách lười biếng (đặt tại GitHub) với hình ảnh. Nó có thể hữu ích cho ai đó. Nó tải hình ảnh trong chuỗi nền. Hình ảnh đang được lưu trữ trên thẻ SD và trong bộ nhớ. Việc triển khai bộ nhớ cache rất đơn giản và chỉ đủ cho bản trình diễn. Tôi giải mã hình ảnh bằng inSampleSize để giảm mức tiêu thụ bộ nhớ. Tôi cũng cố gắng xử lý các chế độ xem tái chế một cách chính xác.

Alt text


983
2018-06-18 08:04



Cảm ơn bạn, tôi đang sử dụng một phiên bản sửa đổi mã của bạn hầu như ở khắp mọi nơi trong dự án của tôi: code.google.com/p/vimeoid/source/browse/apk/src/com/fedorvlasov/… - shaman.sir
Có ai nhìn vào mã của Gilles Debunne như một sự thay thế. Hai sự khác biệt lớn tôi thấy là 1) trong bộ nhớ đệm và thẻ SD và 2) việc sử dụng AsyncTasks thay vì một hồ bơi thread. android-developers.blogspot.com/2010/07/… - Richard
Có một lỗi, đôi khi nó bị sa thải: 10-13 09: 58: 46.738: ERROR / AndroidRuntime (24250): Xử lý không bắt buộc: chủ đề thoát ra ngoài do ngoại lệ không bị bắt 10-13 09: 58: 46,768: ERROR / AndroidRuntime (24250) : java.lang.ArrayIndexOutOfBoundsException: Chỉ mục mảng nằm ngoài phạm vi: 0 10-13 09: 58: 46.768: ERROR / AndroidRuntime (24250): tại java.util.Vector.elementAt (Vector.java:331) 10-13 09: 58: 46.768: ERROR / AndroidRuntime (24250): tại java.util.Vector.get (Vector.java:445) 10-13 09: 58: 46.768: ERROR / AndroidRuntime (24250): tại com.my.app.image .ImageLoader $ PhotosQueue.Clean (ImageLoader.java:91) - Mikooos
Tôi muốn thêm cho những người mới như tôi rằng nếu bạn muốn thêm mã này vào dự án của riêng mình, bạn phải thêm quyền bộ nhớ cache bên ngoài vào tệp kê khai. Cảm ơn bạn - Adam
@BruceHill Không có ảnhQueue trong mã nguồn mới nhất. Bạn dường như đang sử dụng một số phiên bản rất cũ. - Fedor


Tôi khuyên bạn nên sử dụng công cụ nguồn mở Trình tải ảnh toàn cục. Nó ban đầu được dựa trên dự án của Fedor Vlasov Danh sách lười và đã được cải thiện rất nhiều kể từ đó.

  • Tải hình ảnh đa luồng
  • Khả năng điều chỉnh cấu hình của ImageLoader rộng (các trình thực thi luồng, bộ giải mã, bộ giải mã, bộ nhớ đệm và bộ nhớ đĩa, tùy chọn hiển thị hình ảnh và các tùy chọn khác)
  • Khả năng lưu trữ hình ảnh trong bộ nhớ và / hoặc trên sysytem tập tin của thiết bị (hoặc thẻ SD)
  • Khả năng "lắng nghe" quá trình tải
  • Khả năng tùy chỉnh mọi cuộc gọi hình ảnh hiển thị với các tùy chọn được phân tách
  • Hỗ trợ widget
  • Hỗ trợ Android 2.0+


530
2017-12-19 13:53



nếu bạn đang tìm kiếm mã "tải hình ảnh" tuyệt vời mà người tạo của nó xử lý và duy trì như đứa con quý giá của mình (không chỉ một giải pháp một lần), bạn chỉ tìm thấy nó; big ups Nostra - AndroidGecko
Công việc thực sự tuyệt vời, nhưng nó hơi chậm một chút so với listview của tôi. Nếu bạn có thể cho biết trình diễn 'ImageLoader' hiệu suất tốt nhất ... hoặc có thể là do 'DisplayImageOptions'. - dinigo
Tôi thích GridView này rất nhiều nhưng tôi không thể sử dụng nó cho hướng dẫn của tôi. tôi là người mới bắt đầu của android. Tôi làm cho ứng dụng về GridView nhưng ứng dụng của tôi là targetSdkVersion 15 vì vậy tôi cần sử dụng Asynctask cho quá trình trong chủ đề nền. Tôi đã từng sử dụng GridView này nhưng nó không hoạt động. làm thế nào tôi có thể sử dụng nó trong targetSdkVersion 15? - kongkea
Bạn có thể tạo câu hỏi riêng với thẻ [trình tải ảnh phổ quát] - NOSTRA
Sau khi đọc tài liệu android chính thức và cố gắng tự mình làm điều này, tôi khá chắc chắn thư viện này là kết thúc tất cả là tất cả tải hình ảnh. Không thể upvote đủ. - Core


Đa luồng cho hiệu suất, một hướng dẫn của Gilles Debunne.

Đây là từ Blog dành cho nhà phát triển Android. Mã được đề xuất sử dụng:

  • AsyncTasks.
  • Một kích thước cứng, có giới hạn, FIFO cache.
  • Mềm, dễ dàng garbage collectbộ nhớ cache -ed.
  • A trình giữ chỗ  Drawable trong khi bạn tải xuống.

enter image description here


147
2017-08-12 11:07



Nhưng nó được xây dựng trên Android 2.2 (Froyo) ... - Adinia
Nó hoạt động tốt trong 2.1 là tốt. Chỉ cần không sử dụng AndroidHttpClient. - Thomas Ahle
@ thomas-ahle Cảm ơn bạn, tôi thấy AndroidHttpClient đã đưa ra lỗi trong 2.1, vì nó được thực hiện từ 2.2, nhưng không thực sự cố gắng tìm một cái gì đó khác để thay thế nó. - Adinia
@Adina Bạn nói đúng, tôi quên mất. Tuy nhiên không có gì trong công thức mà không thể được thực hiện tốt với một HttpClient bình thường. - Thomas Ahle
Vẫn còn OOM ... - Andro Selva


Cập nhật: Lưu ý rằng câu trả lời này là khá hiệu quả ngay bây giờ. Garbage Collector hoạt động tích cực trên SoftReference và WeakReference, vì vậy mã này KHÔNG thích hợp cho các ứng dụng mới.  (Thay vào đó, hãy thử các thư viện như Trình tải ảnh toàn cục được đề xuất trong các câu trả lời khác.)

Cảm ơn James về mã, và Bao-Long cho đề nghị sử dụng SoftReference. Tôi đã thực hiện các thay đổi của SoftReference trên mã của James. Thật không may SoftReferences khiến hình ảnh của tôi bị thu gom rác quá nhanh. Trong trường hợp của tôi thì không sao nếu không có phần mềm SoftReference, vì kích thước danh sách của tôi bị hạn chế và hình ảnh của tôi nhỏ.

Có một cuộc thảo luận từ một năm trước về SoftReferences trên các nhóm google: liên kết đến chuỗi. Là một giải pháp cho bộ sưu tập rác quá sớm, họ đề xuất khả năng thiết lập thủ công kích thước heap VM bằng dalvik.system.VMRuntime.setMinimumHeapSize (), điều này không hấp dẫn đối với tôi.

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

102
2018-05-05 13:16



bạn có thể tạo ra các thế hệ như thế hệ cứng và mềm. bạn có thể sửa bộ nhớ cache trong thời gian rõ ràng sẽ xóa tất cả các hình ảnh không được truy cập trong 3 giây .. bạn có thể xem dự án giá của Google - AZ_
developer.android.com/reference/java/lang/ref/… SoftReference doc có một lưu ý về bộ nhớ đệm, xem phần "Tránh tham khảo phần mềm cho bộ nhớ đệm". Hầu hết các ứng dụng nên sử dụng android.util.LruCache thay vì tham chiếu mềm. - vokilam
Tôi ngưỡng mộ mã của bạn nhưng bây giờ trong O / S Android mới có thu thập rác 'hung hãn'. Giữ một tham chiếu yếu không có ý nghĩa gì với tôi. - j2emanue
@ j2emanue Bạn nói đúng, như tôi đã cố gắng chỉ ra ở đầu câu trả lời của tôi, SoftReferences là rác được thu thập quá nhanh. Tôi sẽ cố gắng chỉnh sửa câu trả lời này để làm cho câu trả lời thậm chí còn rõ ràng hơn. - TalkLittle


Picasso 

Sử dụng Thư viện Picasso của Jake Wharton. (Thư viện tải hình ảnh hoàn hảo tạo thành nhà phát triển ActionBarSherlock)

Tải xuống hình ảnh mạnh mẽ và thư viện lưu vào bộ nhớ cache dành cho Android.

Hình ảnh thêm bối cảnh rất cần thiết và sự tinh tế trực quan cho các ứng dụng Android. Picasso cho phép tải hình ảnh phức tạp trong ứng dụng của bạn — thường trong một dòng mã!

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

Nhiều cạm bẫy phổ biến của tải hình ảnh trên Android được xử lý tự động bởi Picasso:

Xử lý việc tái chế ImageView và hủy tải xuống trong bộ điều hợp. Chuyển đổi hình ảnh phức tạp với sử dụng bộ nhớ tối thiểu. Bộ nhớ đệm và bộ nhớ đĩa tự động.

Thư viện Picasso Jake Wharton

Glide

Glide là một khung quản lý phương tiện mã nguồn mở nhanh chóng và hiệu quả cho Android kết thúc việc giải mã phương tiện truyền thông, bộ nhớ và bộ nhớ đệm đĩa và chia sẻ tài nguyên thành giao diện đơn giản và dễ sử dụng.

Glide hỗ trợ tìm nạp, giải mã và hiển thị ảnh tĩnh, hình ảnh và GIF động. Glide bao gồm một api linh hoạt cho phép các nhà phát triển cắm vào hầu hết mọi ngăn xếp mạng. Theo mặc định, Glide sử dụng một ngăn xếp dựa trên HttpUrlConnection tùy chỉnh, nhưng cũng bao gồm các thư viện tiện ích cắm vào dự án Volley của Google hoặc thư viện OkHttp của Square thay thế.

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

Glide tập trung chủ yếu vào việc cuộn bất kỳ danh sách hình ảnh nào mượt mà và nhanh nhất có thể, nhưng Glide cũng có hiệu quả đối với hầu hết mọi trường hợp bạn cần tìm nạp, thay đổi kích thước và hiển thị hình ảnh từ xa.

Glide Image Loading Library

Fresco của Facebook 

Fresco là một hệ thống mạnh mẽ để hiển thị hình ảnh trong các ứng dụng Android.

Fresco chăm sóc tải và hiển thị hình ảnh, vì vậy bạn không phải làm như vậy. Nó sẽ tải hình ảnh từ mạng, bộ nhớ cục bộ hoặc tài nguyên cục bộ và hiển thị trình giữ chỗ cho đến khi hình ảnh đã đến. Nó có hai cấp độ bộ nhớ cache; một bộ nhớ và bộ nhớ khác trong bộ nhớ trong.

Fresco Github

Trong Android 4.x và thấp hơn, Fresco đặt hình ảnh trong một khu vực đặc biệt của bộ nhớ Android. Điều này cho phép ứng dụng của bạn chạy nhanh hơn - và gặp phải lỗi OutOfMemoryError đáng sợ ít thường xuyên hơn nhiều.

Tài liệu Fresco


84
2018-04-04 12:35



Picasso là một thư viện được phát triển bởi Square - LordRaydenMK


Trình tải hiệu suất cao - sau khi kiểm tra các phương pháp được đề xuất ở đây, Tôi đã sử dụng Giải pháp của Ben với một số thay đổi -

  1. Tôi nhận ra rằng làm việc với drawables nhanh hơn với bitmap nên tôi sử dụng drawables để thay thế

  2. Sử dụng SoftReference rất tuyệt, nhưng nó làm cho hình ảnh được lưu trong bộ nhớ cache bị xóa quá thường xuyên, vì vậy tôi đã thêm một danh sách Liên kết chứa các tham chiếu hình ảnh, ngăn hình ảnh bị xóa, cho đến khi nó đạt đến kích thước được xác định trước

  3. Để mở InputStream tôi đã sử dụng java.net.URLConnection cho phép tôi sử dụng bộ nhớ cache trên web (trước tiên bạn cần đặt bộ nhớ cache phản hồi, nhưng đó là một câu chuyện khác)

Ma cua toi:

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

77
2017-12-27 23:27



Hoạt động tuyệt vời! BTW có một lỗi đánh máy trong tên lớp. - Mullins
Trong trường hợp nó tiết kiệm cho người khác thời gian: 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
Cảm ơn rất nhiều, đây là một triển khai tốt đẹp. Tôi cũng đặt một trình giữ chỗ khác cho thời điểm bản vẽ được tải để người dùng có thể nhận được một số phản hồi. - Juan Hernandez
Ngoài ra tôi nghĩ là tốt hơn để sử dụng một hàng đợi LIFO trong executorService (mThreadPool) thay vì FIFO mặc định để hình ảnh cuối cùng được yêu cầu (có thể là những cái nhìn thấy được) được nạp đầu tiên. Xem stackoverflow.com/questions/4620061/how-to-create-lifo-executor - Juan Hernandez
@MichaelReed, trong trường hợp bạn là người dùng Eclipse, tôi khuyên bạn nên sử dụng Ctrl-Shift-O (đó là chữ O, không phải là số 0). Nó tự động hóa quá trình thêm nhập khẩu và tổ chức chúng cho bạn. Nếu bạn đang sử dụng Mac, hãy sử dụng Command-Shift-O. - SilithCrowe


Tôi đã theo dõi Đào tạo Android này và tôi nghĩ rằng nó thực hiện công việc tuyệt vời khi tải xuống hình ảnh mà không chặn giao diện người dùng chính. Nó cũng xử lý bộ nhớ đệm và xử lý việc cuộn qua nhiều hình ảnh: Tải các bitmap lớn một cách hiệu quả


75
2018-05-22 06:00



Tôi xin lỗi, tôi chỉ chỉ vào một lớp duy nhất cho ứng dụng Google IO (và tôi đã quá muộn để chỉnh sửa). Bạn nên thực sự nghiên cứu tất cả các lớp tải hình ảnh và bộ nhớ đệm của tiện ích mà bạn có thể tìm thấy trong cùng một gói với lớp cache. - mkuech
Có ai khuyên bạn nên lấy các tập tin DiskLruCache, Image * .java từ thư mục util của ứng dụng iosched để giúp xử lý tải hình ảnh / bộ nhớ đệm cho xem danh sách? Tôi có nghĩa là nó chắc chắn là giá trị theo các hướng dẫn phát triển trực tuyến về chủ đề này nhưng các lớp này (từ iosched) đi xa hơn một chút với mô hình. - Gautam