使用universal-image-loader取消加载图像

时间:2014-03-06 09:56:22

标签: android universal-image-loader

我在每个块中都有带远程图像的GridView。当我尽可能快地滚动它时,它第一次滞后。之后,它已加载每个图像并顺利运行。如何取消加载屏幕上的块的图像?

4 个答案:

答案 0 :(得分:5)

如果您正在使用ViewHolder模式,UIL会自行处理它,您不需要取消为屏幕上的块加载图像!

请参阅this Part of Source Code

else if (isViewWasReused()) {
        L.d(LOG_TASK_CANCELLED_IMAGEAWARE_REUSED, memoryCacheKey);
        listener.onLoadingCancelled(imageUri, imageAware.getWrappedView());
    }

详细了解ViewHolder Pattern

答案 1 :(得分:2)

我认为唯一的解决方案是将其直接加载到视图(而不是位图),而不是在为同一视图加载新图像时使用cancel命令。

public void cancelDisplayTask(ImageAware imageAware)

public void cancelDisplayTask(ImageView imageView)

在ImageLoader中

答案 2 :(得分:0)

import android.os.Process;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 自定义的图片下载 Executor, 可以取消所有已经加入队列的任务.
 * Created by mrsimple on 4/11/16.
 */
public class ImageLoaderExecutor extends ThreadPoolExecutor {

    private List<Future> mTasks = new LinkedList<>();

    public ImageLoaderExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
                               BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, new ImageLoaderExecutor
                .DefaultThreadFactory(Process.THREAD_PRIORITY_BACKGROUND, "uil-pool-"));
    }

    public ImageLoaderExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
                               BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
    }

    public ImageLoaderExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
                               BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
    }

    public ImageLoaderExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
                               BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
                               RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
    }

    @Override
    public Future<?> submit(Runnable task) {
        Future<?> future = super.submit(task);
        mTasks.add(future);
        return future;
    }


    @Override
    public <T> Future<T> submit(Callable<T> task) {
        Future<T> future = super.submit(task);
        mTasks.add(future);
        return future;
    }

    @Override
    public <T> Future<T> submit(Runnable task, T result) {
        Future<T> future = super.submit(task, result);
        mTasks.add(future);
        return future;
    }

    /**
     * 在 ImageLoader中将使用 execute函数提交任务, 在此我们将 Runnable包装为 FutureTask,
     * 使得离线下载时图片的下载可以取消.
     * @param command
     */
    @Override
    public void execute(final Runnable command) {
        Callable<Void> callable = new Callable<Void>() {
            @Override
            public Void call() throws Exception {
                command.run();
                return null;
            }
        } ;
        FutureTask<Void> future = new FutureTask<>(callable) ;
        mTasks.add(future) ;
        super.execute(future);
    }

    /**
     * cancel all task in the list
     */
    public void cancelAllTask() {
        try {
            for (Future f : mTasks) {
                f.cancel(false);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static class DefaultThreadFactory implements ThreadFactory {
        private static final AtomicInteger poolNumber = new AtomicInteger(1);
        private final ThreadGroup group;
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String namePrefix;
        private final int threadPriority;

        public DefaultThreadFactory(int threadPriority, String threadNamePrefix) {
            this.threadPriority = threadPriority;
            this.group = Thread.currentThread().getThreadGroup();
            this.namePrefix = threadNamePrefix + poolNumber.getAndIncrement() + "-thread-";
        }

        public Thread newThread(Runnable r) {
            Thread t = new Thread(this.group, r, this.namePrefix + this.threadNumber.getAndIncrement(), 0L);
            if (t.isDaemon()) {
                t.setDaemon(false);
            }

            t.setPriority(this.threadPriority);
            return t;
        }
    }
}

这是我的自定义ImageLoaderExecutor类:

http://yourdomain.com/category/[something]

答案 3 :(得分:-1)

没有太多意义 - 当您的取消代码执行完毕时,图像可能会被加载,如果它没有被使用,那么垃圾收集器将处理它