批量下载大量图片

来源:互联网 发布:传奇网络加速器 编辑:程序博客网 时间:2024/05/01 18:20

最近由于项目需要,我们要在某个地方一次下载大量的图片,并且将这些图片存放到SD卡中,将地址保存在数据库中,为了保证下载速度和程序运行的效率,我们考虑了以下几个问题:

1.为了保证操作效率,每张图片的下载和存储过程需要单独使用一个线程。

2.需要记录有几张图片下载成功,几张图片下载失败。

3.需要知道什么时候所有的图片下载任务结束。

4.为了保证CPU利用率,我们需要控制同一时刻最多可以开启多少线程。


对于问题1,开启线程下载图片的话,我们可以新建一个Thread()对象来进行图片下载的相关处理,多张图片可以进行循环开启线程,逻辑如下:

for(int i = 0;i < taskCount;i++){new Thread(new Runnable(){        @overridepublic void run(){//下载图片代码...//将图片存入SD卡的代码...//将图片地址存入数据库的代码...}}).start();}



对于问题2,我们可以设置几个变量来记录图片的下载情况

int totalTask;//一共需要下载多少张图片int okTask;//成功的任务int failTask;//失败的任务
这样,在使用的时候,我们可以

new Thread(new Runnable(){        @overridepublic void run(){//下载图片代码Bitmap bm = downloadPic(url);        if(bm != null){            //将图片存入SD卡的代码    ...    //将图片地址存入数据库的代码    ...            okTask++;        }else {             failTask++;         }}}).start();

问题3,判断什么时候所有任务才算结束,这就可以利用问题2中的3个变量,我们定义一个实时监听下载完成状态的方法

isDownloadComplete(final CompleteCallback callback){    new Thread(new Runnable() {    @Overridepublic void run() {    //这个循环等待所有任务完成    while(okTask + failTask < totalTask);    if(okTask == totalTask){    //所有图片下载成功    callback.onComplete();    } else {    //有些图片没有下载成功    callback.onFail();    }    }}


回调的接口定义:

public interface CompleteCallback {public void onComplete();public void onFail();}

第四个问题,也是一个很重要的问题,对于这个问题,我们可以将问题1中的循环开启多个线程改为用线程池对线程进行操作,这样既控制了同时启动的线程数量,又可以更好的管理启动的线程。

建立线程池,我们使用的是android 所带的ExecutorService ,关于这个服务,请参考下面的文章:

http://blog.csdn.net/hudashi/article/details/7008583

http://blog.sina.com.cn/s/blog_6151984a0100krj8.html

这样,问题1中的代码可以改为:

//nThreads 代表当前可以开启的线程数量public void downloadPic() {    ExecutorService executorService = Executors.newFixedThreadPool(nThreads);    for(int i = 0;i < totalTask;i++){        executorService.submit(new Runnable() {    @Override    public void run() {        //下载图片代码        Bitmap bm = downloadPic(url);                if(bm != null){                    //将图片存入SD卡的代码            ...            //将图片地址存入数据库的代码            ...                    okTask++;                }else {                    failTask++;                }            }        }    }}

这样,我们就实现了一个批量下载图片的大体框架,我们假设将上述的过程封装成了一个类,那么我们在使用时就可以:

BitmapDownloadHelper helper = new BitmapDownloadHelper(需要传入的url数据等);//这个就是上面的下载过程helper.downloadPic();helper.isDownloadComplete(new CompleteCallback(){    @override    public void onComplete(){        //下载成功的后续处理    }    @override    public void onFail(){        //下载失败的后续处理    }});


好了,就写到这里,如有错误或者补充,还望不吝赐教。



0 0
原创粉丝点击