Android线程池的使用(单线程池)

应用情景

比如有多个下载任务(下载短视频、动画文件),需要按一定的顺序进行,我们就可以考虑使用单线程池,然后使用一个任务队列,每来一个下载任务就往任务队列里添加。使用单线程的目的主要是能够保证任务按照一定的顺序执行,同时能够减少网络流量的消耗。

结构设计

单线程池多任务下载,首先,我们肯定得有一个线程池,来执行下载任务:ExecutorService mExecutor = Executors.newSingleThreadExecutor()。然后,我们得有一个任务队列用来装载下载任务:List mTask = Collections.synchronizedList(new ArrayList()),DownloadTask是一个Callable类型,具体执行下载文件的代码放到call()方法中。最后,我们得定义addDownloadTask(添加下载任务)、isDownloading(判断任务是否处于下载的状态)、cancelDownloadTask(取消下载任务)等方法。

1. DownloadTask

public  class DownloadTask implements Callable {
    private DownloadTask mTask = this;
    public DownloadItem mDownloadItem;
    private String mFilePath = "";
    public IFileDownloadListener mListener;
    private HttpResponseHandler mResponseHandler;

    public DownloadTask(DownloadItem item, String filePath, IFileDownloadListener listener) {
        mDownloadItem = item;
        mFilePath = filePath;
        mListener = listener;
        init();
    }

    @Override
    public Boolean call() {
        try {
            FileUtils.downloadFile(mDownloadItem.url, mFilePath, mResponseHandler);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    private void init() {
        mResponseHandler = new HttpResponseHandler() {
            @Override
            public void onSuccess(File content) {
                if (content == null) {
                    DownloadManager.getInstance().removeTask(mTask);
                    return;
                }
                if (mListener != null) {
                    mListener.onSuccess(mDownloadItem, mFilePath);
                } else {
                    content.delete();
                    if (mListener != null)
                        mListener.onFailed(mDownloadItem);
                }
                DownloadManager.getInstance().removeTask(mTask);
            }

            @Override
            public void onFailure(Throwable info, File content) {
                if (mListener != null) {
                    mListener.onFailed(mDownloadItem);
                }
                DownloadManager.getInstance().removeTask(mTask);
            }
        };
    }
}

2. DownloadManager

public class DownloadManager {
    private static DownloadManager sDownloadManager = null;

    private List mTask = null;
    private ExecutorService mExecutor = null;

    private DownloadManager() {
        mExecutor = Executors.newSingleThreadExecutor();
        mTask = Collections.synchronizedList(new ArrayList());
    }

    public static DownloadManager getInstance() {
        if (sDownloadManager == null)
            sDownloadManager = new DownloadManager();
        return sDownloadManager;
    }

    /**
     * 判断是否处于下载状态
     */
    public boolean isDownloading(DownloadItem item, String filePath) throws NullPointerException {
        if (item == null || filePath == null)
            throw new NullPointerException();
        for (DownloadTask task : mTask) {
            if (task.mFilePath.equals(filePath)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 添加下载任务到下载队列里,同时将下载任务放到线程池中
     */
    public boolean addDownloadTask(DownloadItem item, String filePath, IFileDownloadListener listener) {
        for (DownloadTask task : mTask) {
            if (task.mFilePath.equals(filePath)) {
                return false;
            }
        }
        DownloadTask newTask = new DownloadTask(item, filePath, listener);
        mTask.add(newTask);
        mExecutor.submit(newTask);
        listener.onStart(item);
        return true;
    }

    /**
     * 删除下载任务
     */
    public boolean cancelDownloadTask(DownloadItem item, String filePath) throws NullPointerException {
        if (item == null || filePath == null)
            for (DownloadTask task : mTask) {
                if (task.mFilePath.equals(filePath)) {
                    mTask.remove(task);
                    // 触发取消下载回调方法
                    if (task.mListener != null)
                        task.mListener.onCancel(item);
                    task = null;
                    return true;
                }
            }

        return false;
    }

    /**
     * 删除下载任务
     */
    public void removeTask(DownloadTask task) {
        mTask.remove(task);
    }
}

说明

上文大致给出了单线程池多任务下载的代码结构模型,其中还有部分代码没有给出,这些代码大家可以根据自己的业务逻辑进行设计(欢迎大家指正!!!)。

你可能感兴趣的:(Android线程池的使用(单线程池))