AsyncTask实现多任务多线程断点续传下载

  这篇博客是AsyncTask下载系列的最后一篇文章,前面写了关于断点续传的和多线程下载的博客,这篇是在前两篇的基础上面实现的,有兴趣的可以去看下。

  一、AsyncTask实现断点续传

  二、AsyncTask实现多线程断点续传

  这里模拟应用市场app下载实现了一个Demo,因为只有一个界面,所以没有将下载放到Service中,而是直接在Activity中创建。在正式的项目中,下载都是放到Service中,然后通过BroadCast通知界面更新进度。

  上代码之前,先看下demo的运行效果图吧。

 

  下面我们看代码,这里每一个文件的下载定义一个Downloador来管理下载该文件的所有线程(暂停、下载等)。Downloador创建3个DownloadTask(这里定义每个文件分配3个线程下载)来下载该文件特定的起止位置。这里要通过文件的大小来计算每个线程所下载的起止位置,详细可以参考《AsyncTask实现多线程断点续传》。

  1、Downloador类

  1 package com.bbk.lling.multitaskdownload.downloador;
  2 
  3 import android.content.Context;
  4 import android.content.Intent;
  5 import android.os.AsyncTask;
  6 import android.os.Bundle;
  7 import android.os.Handler;
  8 import android.os.Message;
  9 import android.text.TextUtils;
 10 import android.util.Log;
 11 import android.widget.Toast;
 12 
 13 import com.bbk.lling.multitaskdownload.beans.AppContent;
 14 import com.bbk.lling.multitaskdownload.beans.DownloadInfo;
 15 import com.bbk.lling.multitaskdownload.db.DownloadFileDAO;
 16 import com.bbk.lling.multitaskdownload.db.DownloadInfoDAO;
 17 import com.bbk.lling.multitaskdownload.utils.DownloadUtils;
 18 
 19 import org.apache.http.HttpResponse;
 20 import org.apache.http.client.HttpClient;
 21 import org.apache.http.client.methods.HttpGet;
 22 import org.apache.http.impl.client.DefaultHttpClient;
 23 
 24 import java.util.ArrayList;
 25 import java.util.List;
 26 import java.util.concurrent.Executor;
 27 import java.util.concurrent.Executors;
 28 
 29 /**
 30  * @Class: Downloador
 31  * @Description: 任务下载器
 32  * @author: lling(www.cnblogs.com/liuling)
 33  * @Date: 2015/10/13
 34  */
 35 public class Downloador {
 36     public static final String TAG = "Downloador";
 37     private static final int THREAD_POOL_SIZE = 9;  //线程池大小为9
 38     private static final int THREAD_NUM = 3;  //每个文件3个线程下载
 39     private static final int GET_LENGTH_SUCCESS = 1;
 40     public static final Executor THREAD_POOL_EXECUTOR = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
 41 
 42     private List<DownloadTask> tasks;
 43     private InnerHandler handler = new InnerHandler();
 44 
 45     private AppContent appContent; //待下载的应用
 46     private long downloadLength; //下载过程中记录已下载大小
 47     private long fileLength;
 48     private Context context;
 49     private String downloadPath;
 50 
 51     public Downloador(Context context, AppContent appContent) {
 52         this.context = context;
 53         this.appContent = appContent;
 54         this.downloadPath = DownloadUtils.getDownloadPath();
 55     }
 56 
 57     /**
 58      * 开始下载
 59      */
 60     public void download() {
 61         if(TextUtils.isEmpty(downloadPath)) {
 62             Toast.makeText(context, "未找到SD卡", Toast.LENGTH_SHORT).show();
 63             return;
 64         }
 65         if(appContent == null) {
 66             throw new IllegalArgumentException("download content can not be null");
 67         }
 68         new Thread() {
 69             @Override
 70             public void run() {
 71                 //获取文件大小
 72                 HttpClient client = new DefaultHttpClient();
 73                 HttpGet request = new HttpGet(appContent.getUrl());
 74                 HttpResponse response = null;
 75                 try {
 76                     response = client.execute(request);
 77                     fileLength = response.getEntity().getContentLength();
 78                 } catch (Exception e) {
 79                     Log.e(TAG, e.getMessage());
 80                 } finally {
 81                     if (request != null) {
 82                         request.abort();
 83                     }
 84                 }
 85                 //计算出该文件已经下载的总长度
 86                 List<DownloadInfo> lists = DownloadInfoDAO.getInstance(context.getApplicationContext())
 87                         .getDownloadInfosByUrl(appContent.getUrl());
 88                 for (DownloadInfo info : lists) {
 89                     downloadLength += info.getDownloadLength();
 90                 }
 91 
 92                 //插入文件下载记录到数据库
 93                 DownloadFileDAO.getInstance(context.getApplicationContext()).insertDownloadFile(appContent);
 94                 Message.obtain(handler, GET_LENGTH_SUCCESS).sendToTarget();
 95             }
 96         }.start();
 97     }
 98 
 99     /**
100      * 开始创建AsyncTask下载
101      */
102     private void beginDownload() {
103         Log.e(TAG, "beginDownload" + appContent.getUrl());
104         appContent.setStatus(AppContent.Status.WAITING);
105         long blockLength = fileLength / THREAD_NUM;
106         for (int i = 0; i < THREAD_NUM; i++) {
107             long beginPosition = i * blockLength;//每条线程下载的开始位置
108             long endPosition = (i + 1) * blockLength;//每条线程下载的结束位置
109             if (i == (THREAD_NUM - 1)) {
110                 endPosition = fileLength;//如果整个文件的大小不为线程个数的整数倍,则最后一个线程的结束位置即为文件的总长度
111             }
112             DownloadTask task = new DownloadTask(i, beginPosition, endPosition, this, context);
113             task.executeOnExecutor(THREAD_POOL_EXECUTOR, appContent.getUrl());
114             if(tasks == null) {
115                 tasks = new ArrayList<DownloadTask>();
116             }
117             tasks.add(task);
118         }
119     }
120 
121     /**
122      * 暂停下载
123      */
124     public void pause() {
125         for (DownloadTask task : tasks) {
126             if (task != null && (task.getStatus() == AsyncTask.Status.RUNNING || !task.isCancelled())) {
127                 task.cancel(true);
128             }
129         }
130         tasks.clear();
131         appContent.setStatus(AppContent.Status.PAUSED);
132         DownloadFileDAO.getInstance(context.getApplicationContext()).updateDownloadFile(appContent);
133     }
134 
135     /**
136      * 将已下载大小归零
137      */
138     protected synchronized void resetDownloadLength() {
139         this.downloadLength = 0;
140     }
141 
142     /**
143      * 添加已下载大小
144      * 多线程访问需加锁
145      * @param size
146      */
147     protected synchronized void updateDownloadLength(long size){
148         this.downloadLength += size;
149         //通知更新界面
150         int percent = (int)((float)downloadLength * 100 / (float)fileLength);
151         appContent.setDownloadPercent(percent);
152         if(percent == 100 || downloadLength == fileLength) {
153             appContent.setDownloadPercent(100); //上面计算有时候会有点误差,算到percent=99
154             appContent.setStatus(AppContent.Status.FINISHED);
155             DownloadFileDAO.getInstance(context.getApplicationContext()).updateDownloadFile(appContent);
156         }
157         Intent intent = new Intent(Constants.DOWNLOAD_MSG);
158         if(appContent.getStatus() == AppContent.Status.WAITING) {
159             appContent.setStatus(AppContent.Status.DOWNLOADING);
160         }
161         Bundle bundle = new Bundle();
162         bundle.putParcelable("appContent", appContent);
163         intent.putExtras(bundle);
164         context.sendBroadcast(intent);
165     }
166 
167     protected String getDownloadPath() {
168         return downloadPath;
169     }
170 
171     private class InnerHandler extends Handler {
172         @Override
173         public void handleMessage(Message msg) {
174             switch (msg.what) {
175                 case GET_LENGTH_SUCCESS :
176                     beginDownload();
177                     break;
178             }
179             super.handleMessage(msg);
180         }
181     }
182 }

  2、DownloadTask类

  1 package com.bbk.lling.multitaskdownload.downloador;
  2 
  3 import android.content.Context;
  4 import android.os.AsyncTask;
  5 import android.util.Log;
  6 
  7 import com.bbk.lling.multitaskdownload.beans.DownloadInfo;
  8 import com.bbk.lling.multitaskdownload.db.DownloadInfoDAO;
  9 
 10 import org.apache.http.Header;
 11 import org.apache.http.HttpResponse;
 12 import org.apache.http.client.HttpClient;
 13 import org.apache.http.client.methods.HttpGet;
 14 import org.apache.http.impl.client.DefaultHttpClient;
 15 import org.apache.http.message.BasicHeader;
 16 
 17 import java.io.File;
 18 import java.io.IOException;
 19 import java.io.InputStream;
 20 import java.io.OutputStream;
 21 import java.io.RandomAccessFile;
 22 import java.net.MalformedURLException;
 23 
 24 /**
 25  * @Class: DownloadTask
 26  * @Description: 文件下载AsyncTask
 27  * @author: lling(www.cnblogs.com/liuling)
 28  * @Date: 2015/10/13
 29  */
 30 public class DownloadTask extends AsyncTask<String, Integer , Long> {
 31     private static final String TAG = "DownloadTask";
 32 
 33     private int taskId;
 34     private long beginPosition;
 35     private long endPosition;
 36     private long downloadLength;
 37     private String url;
 38     private Downloador downloador;
 39     private DownloadInfoDAO downloadInfoDAO;
 40 
 41 
 42     public DownloadTask(int taskId, long beginPosition, long endPosition, Downloador downloador,
 43                         Context context) {
 44         this.taskId = taskId;
 45         this.beginPosition = beginPosition;
 46         this.endPosition = endPosition;
 47         this.downloador = downloador;
 48         downloadInfoDAO = DownloadInfoDAO.getInstance(context.getApplicationContext());
 49     }
 50 
 51     @Override
 52     protected void onPreExecute() {
 53         Log.e(TAG, "onPreExecute");
 54     }
 55 
 56     @Override
 57     protected void onPostExecute(Long aLong) {
 58         Log.e(TAG, url + "taskId:" + taskId + "executed");
 59 //        downloador.updateDownloadInfo(null);
 60     }
 61 
 62     @Override
 63     protected void onProgressUpdate(Integer... values) {
 64         //通知downloador增加已下载大小
 65 //        downloador.updateDownloadLength(values[0]);
 66     }
 67 
 68     @Override
 69     protected void onCancelled() {
 70         Log.e(TAG, "onCancelled");
 71 //        downloador.updateDownloadInfo(null);
 72     }
 73 
 74     @Override
 75     protected Long doInBackground(String... params) {
 76         //这里加判断的作用是:如果还处于等待就暂停了,运行到这里已经cancel了,就直接退出
 77         if(isCancelled()) {
 78             return null;
 79         }
 80         url = params[0];
 81         if(url == null) {
 82             return null;
 83         }
 84         HttpClient client = new DefaultHttpClient();
 85         HttpGet request = new HttpGet(url);
 86         HttpResponse response;
 87         InputStream is;
 88         RandomAccessFile fos = null;
 89         OutputStream output = null;
 90 
 91         DownloadInfo downloadInfo = null;
 92         try {
 93             //本地文件
 94             File file = new File(downloador.getDownloadPath() + File.separator + url.substring(url.lastIndexOf("/") + 1));
 95 
 96             //获取之前下载保存的信息
 97             downloadInfo = downloadInfoDAO.getDownloadInfoByTaskIdAndUrl(taskId, url);
 98             //从之前结束的位置继续下载
 99             //这里加了判断file.exists(),判断是否被用户删除了,如果文件没有下载完,但是已经被用户删除了,则重新下载
100             if(file.exists() && downloadInfo != null) {
101                 if(downloadInfo.isDownloadSuccess() == 1) {
102                     //下载完成直接结束
103                     return null;
104                 }
105                 beginPosition = beginPosition + downloadInfo.getDownloadLength();
106                 downloadLength = downloadInfo.getDownloadLength();
107             }
108             if(!file.exists()) {
109                 //如果此task已经下载完,但是文件被用户删除,则需要重新设置已下载长度,重新下载
110                 downloador.resetDownloadLength();
111             }
112 
113             //设置下载的数据位置beginPosition字节到endPosition字节
114             Header header_size = new BasicHeader("Range", "bytes=" + beginPosition + "-" + endPosition);
115             request.addHeader(header_size);
116             //执行请求获取下载输入流
117             response = client.execute(request);
118             is = response.getEntity().getContent();
119 
120             //创建文件输出流
121             fos = new RandomAccessFile(file, "rw");
122             //从文件的size以后的位置开始写入
123             fos.seek(beginPosition);
124 
125             byte buffer [] = new byte[1024];
126             int inputSize = -1;
127             while((inputSize = is.read(buffer)) != -1) {
128                 fos.write(buffer, 0, inputSize);
129                 downloadLength += inputSize;
130                 downloador.updateDownloadLength(inputSize);
131 
132                 //如果暂停了,需要将下载信息存入数据库
133                 if (isCancelled()) {
134                     if(downloadInfo == null) {
135                         downloadInfo = new DownloadInfo();
136                     }
137                     downloadInfo.setUrl(url);
138                     downloadInfo.setDownloadLength(downloadLength);
139                     downloadInfo.setTaskId(taskId);
140                     downloadInfo.setDownloadSuccess(0);
141                     //保存下载信息到数据库
142                     downloadInfoDAO.insertDownloadInfo(downloadInfo);
143                     return null;
144                 }
145             }
146         } catch (MalformedURLException e) {
147             Log.e(TAG, e.getMessage());
148         } catch (IOException e) {
149             Log.e(TAG, e.getMessage());
150         } finally{
151             try{
152                 if (request != null) {
153                     request.abort();
154                 }
155                 if(output != null) {
156                     output.close();
157                 }
158                 if(fos != null) {
159                     fos.close();
160                 }
161             } catch(Exception e) {
162                 e.printStackTrace();
163             }
164         }
165         //执行到这里,说明该task已经下载完了
166         if(downloadInfo == null) {
167             downloadInfo = new DownloadInfo();
168         }
169         downloadInfo.setUrl(url);
170         downloadInfo.setDownloadLength(downloadLength);
171         downloadInfo.setTaskId(taskId);
172         downloadInfo.setDownloadSuccess(1);
173         //保存下载信息到数据库
174         downloadInfoDAO.insertDownloadInfo(downloadInfo);
175         return null;
176     }
177 }

  Downloador和DownloadTask只这个例子的核心代码,下面是关于数据库的,因为要实现断点续传必须要在暂停的时候将每个线程下载的位置记录下来,方便下次继续下载时读取。这里有两个表,一个是存放每个文件的下载状态的,一个是存放每个文件对应的每个线程的下载状态的。

  3、DBHelper

 1 package com.bbk.lling.multitaskdownload.db;
 2 
 3 import android.content.Context;
 4 import android.database.sqlite.SQLiteDatabase;
 5 import android.database.sqlite.SQLiteOpenHelper;
 6 
 7 /**
 8  * @Class: DBHelper
 9  * @Description: 数据库帮助类
10  * @author: lling(www.cnblogs.com/liuling)
11  * @Date: 2015/10/14
12  */
13 public class DBHelper extends SQLiteOpenHelper {
14 
15     public DBHelper(Context context) {
16         super(context, "download.db", null, 1);
17     }
18 
19     @Override
20     public void onCreate(SQLiteDatabase db) {
21         db.execSQL("create table download_info(_id INTEGER PRIMARY KEY AUTOINCREMENT, task_id INTEGER, "
22                 + "download_length INTEGER, url VARCHAR(255), is_success INTEGER)");
23         db.execSQL("create table download_file(_id INTEGER PRIMARY KEY AUTOINCREMENT, app_name VARCHAR(255), "
24                 + "url VARCHAR(255), download_percent INTEGER, status INTEGER)");
25     }
26 
27     @Override
28     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
29 
30     }
31 }

  4、DownloadFileDAO,文件下载状态的数据库操作类

  1 package com.bbk.lling.multitaskdownload.db;
  2 
  3 import android.content.Context;
  4 import android.database.Cursor;
  5 import android.database.sqlite.SQLiteDatabase;
  6 import android.text.TextUtils;
  7 import android.util.Log;
  8 
  9 import com.bbk.lling.multitaskdownload.beans.AppContent;
 10 
 11 import java.util.ArrayList;
 12 import java.util.List;
 13 
 14 /**
 15  * @Class: DownloadFileDAO
 16  * @Description: 每个文件下载状态记录的数据库操作类
 17  * @author: lling(www.cnblogs.com/liuling)
 18  * @Date: 2015/10/13
 19  */
 20 public class DownloadFileDAO {
 21     private static final String TAG = "DownloadFileDAO";
 22     private static DownloadFileDAO dao=null;
 23     private Context context;
 24     private DownloadFileDAO(Context context) {
 25         this.context=context;
 26     }
 27 
 28     synchronized public static DownloadFileDAO getInstance(Context context){
 29         if(dao==null){
 30             dao=new DownloadFileDAO(context);
 31         }
 32         return dao;
 33     }
 34 
 35     /**
 36      * 获取数据库连接
 37      * @return
 38      */
 39     public SQLiteDatabase getConnection() {
 40         SQLiteDatabase sqliteDatabase = null;
 41         try {
 42             sqliteDatabase= new DBHelper(context).getReadableDatabase();
 43         } catch (Exception e) {
 44             Log.e(TAG, e.getMessage());
 45         }
 46         return sqliteDatabase;
 47     }
 48 
 49     /**
 50      * 插入数据
 51      * @param appContent
 52      */
 53     public void insertDownloadFile(AppContent appContent) {
 54         if(appContent == null) {
 55             return;
 56         }
 57         //如果本地已经存在,直接修改
 58         if(getAppContentByUrl(appContent.getUrl()) != null) {
 59             updateDownloadFile(appContent);
 60             return;
 61         }
 62         SQLiteDatabase database = getConnection();
 63         try {
 64             String sql = "insert into download_file(app_name, url, download_percent, status) values (?,?,?,?)";
 65             Object[] bindArgs = { appContent.getName(), appContent.getUrl(), appContent.getDownloadPercent()
 66                     , appContent.getStatus().getValue()};
 67             database.execSQL(sql, bindArgs);
 68         } catch (Exception e) {
 69             Log.e(TAG, e.getMessage());
 70         } finally {
 71             if (null != database) {
 72                 database.close();
 73             }
 74         }
 75     }
 76 
 77     /**
 78      * 根据url获取下载文件信息
 79      * @param url
 80      * @return
 81      */
 82     public AppContent getAppContentByUrl(String url) {
 83         if(TextUtils.isEmpty(url)) {
 84             return null;
 85         }
 86         SQLiteDatabase database = getConnection();
 87         AppContent appContent = null;
 88         Cursor cursor = null;
 89         try {
 90             String sql = "select * from download_file where url=?";
 91             cursor = database.rawQuery(sql, new String[] { url });
 92             if (cursor.moveToNext()) {
 93                 appContent = new AppContent(cursor.getString(1), cursor.getString(2));
 94                 appContent.setDownloadPercent(cursor.getInt(3));
 95                 appContent.setStatus(AppContent.Status.getByValue(cursor.getInt(4)));
 96             }
 97         } catch (Exception e) {
 98             Log.e(TAG, e.getMessage());
 99         } finally {
100             if (null != database) {
101                 database.close();
102             }
103             if (null != cursor) {
104                 cursor.close();
105             }
106         }
107         return appContent;
108     }
109 
110     /**
111      * 更新下载信息
112      * @param appContent
113      */
114     public void updateDownloadFile(AppContent appContent) {
115         if(appContent == null) {
116             return;
117         }
118         SQLiteDatabase database = getConnection();
119         try {
120             Log.e(TAG, "update download_file,app name:" + appContent.getName() + ",url:" + appContent.getUrl()
121                     + ",percent" + appContent.getDownloadPercent() + ",status:" + appContent.getStatus().getValue());
122             String sql = "update download_file set app_name=?, url=?, download_percent=?, status=? where url=?";
123             Object[] bindArgs = {appContent.getName(), appContent.getUrl(), appContent.getDownloadPercent()
124                     , appContent.getStatus().getValue(), appContent.getUrl()};
125             database.execSQL(sql, bindArgs);
126         } catch (Exception e) {
127             Log.e(TAG, e.getMessage());
128         } finally {
129             if (null != database) {
130                 database.close();
131             }
132         }
133     }
134 
135     /**
136      * 获取所有下载文件记录
137      * @return
138      */
139     public List<AppContent> getAll() {
140         SQLiteDatabase database = getConnection();
141         List<AppContent> list = new ArrayList<AppContent>();
142         Cursor cursor = null;
143         try {
144             String sql = "select * from download_file";
145             cursor = database.rawQuery(sql, null);
146             while (cursor.moveToNext()) {
147                 AppContent appContent = new AppContent(cursor.getString(1), cursor.getString(2));
148                 appContent.setDownloadPercent(cursor.getInt(3));
149                 appContent.setStatus(AppContent.Status.getByValue(cursor.getInt(4)));
150                 list.add(appContent);
151             }
152         } catch (Exception e) {
153             Log.e(TAG, e.getMessage());
154         } finally {
155             if (null != database) {
156                 database.close();
157             }
158             if (null != cursor) {
159                 cursor.close();
160             }
161         }
162         return list;
163     }
164 
165     /**
166      * 根据url删除记录
167      * @param url
168      */
169     public void delByUrl(String url) {
170         if(TextUtils.isEmpty(url)) {
171             return;
172         }
173         SQLiteDatabase database = getConnection();
174         try {
175             String sql = "delete from download_file where url=?";
176             Object[] bindArgs = { url };
177             database.execSQL(sql, bindArgs);
178         } catch (Exception e) {
179             Log.e(TAG, e.getMessage());
180         } finally {
181             if (null != database) {
182                 database.close();
183             }
184         }
185     }
186 
187 }

  5、DownloadInfoDAO,每个线程对应下载状态的数据库操作类

  1 package com.bbk.lling.multitaskdownload.db;
  2 
  3 import android.content.Context;
  4 import android.database.Cursor;
  5 import android.database.sqlite.SQLiteDatabase;
  6 import android.text.TextUtils;
  7 import android.util.Log;
  8 
  9 import com.bbk.lling.multitaskdownload.beans.DownloadInfo;
 10 
 11 import java.util.ArrayList;
 12 import java.util.List;
 13 
 14 /**
 15  * @Class: DownloadInfoDAO
 16  * @Description: 每个单独线程下载信息记录的数据库操作类
 17  * @author: lling(www.cnblogs.com/liuling)
 18  * @Date: 2015/10/13
 19  */
 20 public class DownloadInfoDAO {
 21     private static final String TAG = "DownloadInfoDAO";
 22     private static DownloadInfoDAO dao=null;
 23     private Context context;
 24     private  DownloadInfoDAO(Context context) {
 25         this.context=context;
 26     }
 27 
 28     synchronized public static DownloadInfoDAO getInstance(Context context){
 29         if(dao==null){
 30             dao=new DownloadInfoDAO(context);
 31         }
 32         return dao;
 33     }
 34 
 35     /**
 36      * 获取数据库连接
 37      * @return
 38      */
 39     public SQLiteDatabase getConnection() {
 40         SQLiteDatabase sqliteDatabase = null;
 41         try {
 42             sqliteDatabase= new DBHelper(context).getReadableDatabase();
 43         } catch (Exception e) {
 44             Log.e(TAG, e.getMessage());
 45         }
 46         return sqliteDatabase;
 47     }
 48 
 49     /**
 50      * 插入数据
 51      * @param downloadInfo
 52      */
 53     public void insertDownloadInfo(DownloadInfo downloadInfo) {
 54         if(downloadInfo == null) {
 55             return;
 56         }
 57         //如果本地已经存在,直接修改
 58         if(getDownloadInfoByTaskIdAndUrl(downloadInfo.getTaskId(), downloadInfo.getUrl()) != null) {
 59             updateDownloadInfo(downloadInfo);
 60             return;
 61         }
 62         SQLiteDatabase database = getConnection();
 63         try {
 64             String sql = "insert into download_info(task_id, download_length, url, is_success) values (?,?,?,?)";
 65             Object[] bindArgs = { downloadInfo.getTaskId(), downloadInfo.getDownloadLength(),
 66                     downloadInfo.getUrl(), downloadInfo.isDownloadSuccess()};
 67             database.execSQL(sql, bindArgs);
 68         } catch (Exception e) {
 69             Log.e(TAG, e.getMessage());
 70         } finally {
 71             if (null != database) {
 72                 database.close();
 73             }
 74         }
 75     }
 76 
 77     public List<DownloadInfo> getDownloadInfosByUrl(String url) {
 78         if(TextUtils.isEmpty(url)) {
 79             return null;
 80         }
 81         SQLiteDatabase database = getConnection();
 82         List<DownloadInfo> list = new ArrayList<DownloadInfo>();
 83         Cursor cursor = null;
 84         try {
 85             String sql = "select * from download_info where url=?";
 86             cursor = database.rawQuery(sql, new String[] { url });
 87             while (cursor.moveToNext()) {
 88                 DownloadInfo info = new DownloadInfo();
 89                 info.setTaskId(cursor.getInt(1));
 90                 info.setDownloadLength(cursor.getLong(2));
 91                 info.setDownloadSuccess(cursor.getInt(4));
 92                 info.setUrl(cursor.getString(3));
 93                 list.add(info);
 94             }
 95         } catch (Exception e) {
 96             e.printStackTrace();
 97         } finally {
 98             if (null != database) {
 99                 database.close();
100             }
101             if (null != cursor) {
102                 cursor.close();
103             }
104         }
105         return list;
106     }
107 
108     /**
109      * 根据taskid和url获取下载信息
110      * @param taskId
111      * @param url
112      * @return
113      */
114     public DownloadInfo getDownloadInfoByTaskIdAndUrl(int taskId, String url) {
115         if(TextUtils.isEmpty(url)) {
116             return null;
117         }
118         SQLiteDatabase database = getConnection();
119         DownloadInfo info = null;
120         Cursor cursor = null;
121         try {
122             String sql = "select * from download_info where url=? and task_id=?";
123             cursor = database.rawQuery(sql, new String[] { url, String.valueOf(taskId) });
124             if (cursor.moveToNext()) {
125                 info = new DownloadInfo();
126                 info.setTaskId(cursor.getInt(1));
127                 info.setDownloadLength(cursor.getLong(2));
128                 info.setDownloadSuccess(cursor.getInt(4));
129                 info.setUrl(cursor.getString(3));
130             }
131         } catch (Exception e) {
132             Log.e(TAG, e.getMessage());
133         } finally {
134             if (null != database) {
135                 database.close();
136             }
137             if (null != cursor) {
138                 cursor.close();
139             }
140         }
141         return info;
142     }
143 
144     /**
145      * 更新下载信息
146      * @param downloadInfo
147      */
148     public void updateDownloadInfo(DownloadInfo downloadInfo) {
149         if(downloadInfo == null) {
150             return;
151         }
152         SQLiteDatabase database = getConnection();
153         try {
154             String sql = "update download_info set download_length=?, is_success=? where task_id=? and url=?";
155             Object[] bindArgs = { downloadInfo.getDownloadLength(), downloadInfo.isDownloadSuccess(),
156                     downloadInfo.getTaskId(), downloadInfo.getUrl() };
157             database.execSQL(sql, bindArgs);
158         } catch (Exception e) {
159             Log.e(TAG, e.getMessage());
160         } finally {
161             if (null != database) {
162                 database.close();
163             }
164         }
165     }
166 
167 }

  具体的界面和使用代码我就不贴代码了,代码有点多。需要的可以下载Demo的源码看看。

  因为还没有花太多时间去测,里面难免会有些bug,如果大家发现什么问题,欢迎留言探讨,谢谢!

  

源码下载:https://github.com/liuling07/MultiTaskAndThreadDownload

 

原创内容,转载请注明出处:http://www.cnblogs.com/liuling/p/2015-10-16-01.html

posted @ 2015-10-16 21:29  残剑_  阅读(6882)  评论(0编辑  收藏  举报