激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專(zhuān)注于服務(wù)器技術(shù)及軟件下載分享
分類(lèi)導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Android - Android 使用AsyncTask實(shí)現(xiàn)多任務(wù)多線程斷點(diǎn)續(xù)傳下載

Android 使用AsyncTask實(shí)現(xiàn)多任務(wù)多線程斷點(diǎn)續(xù)傳下載

2021-04-06 14:04殘劍_ Android

這篇文章主要介紹了Android 使用AsyncTask實(shí)現(xiàn)多任務(wù)多線程斷點(diǎn)續(xù)傳下載的相關(guān)資料,需要的朋友可以參考下

這篇博客是AsyncTask下載系列的最后一篇文章,前面寫(xiě)了關(guān)于斷點(diǎn)續(xù)傳的和多線程下載的博客,這篇是在前兩篇的基礎(chǔ)上面實(shí)現(xiàn)的,有興趣的可以去看下。

  一、AsyncTask實(shí)現(xiàn)斷點(diǎn)續(xù)傳

  二、AsyncTask實(shí)現(xiàn)多線程斷點(diǎn)續(xù)傳

  這里模擬應(yīng)用市場(chǎng)app下載實(shí)現(xiàn)了一個(gè)Demo,因?yàn)橹挥幸粋€(gè)界面,所以沒(méi)有將下載放到Service中,而是直接在Activity中創(chuàng)建。在正式的項(xiàng)目中,下載都是放到Service中,然后通過(guò)BroadCast通知界面更新進(jìn)度。

  上代碼之前,先看下demo的運(yùn)行效果圖吧。

Android 使用AsyncTask實(shí)現(xiàn)多任務(wù)多線程斷點(diǎn)續(xù)傳下載

  下面我們看代碼,這里每一個(gè)文件的下載定義一個(gè)Downloador來(lái)管理下載該文件的所有線程(暫停、下載等)。Downloador創(chuàng)建3個(gè)DownloadTask(這里定義每個(gè)文件分配3個(gè)線程下載)來(lái)下載該文件特定的起止位置。這里要通過(guò)文件的大小來(lái)計(jì)算每個(gè)線程所下載的起止位置,詳細(xì)可以參考《AsyncTask實(shí)現(xiàn)多線程斷點(diǎn)續(xù)傳》。

  1、Downloador類(lèi)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
package com.bbk.lling.multitaskdownload.downloador;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import com.bbk.lling.multitaskdownload.beans.AppContent;
import com.bbk.lling.multitaskdownload.beans.DownloadInfo;
import com.bbk.lling.multitaskdownload.db.DownloadFileDAO;
import com.bbk.lling.multitaskdownload.db.DownloadInfoDAO;
import com.bbk.lling.multitaskdownload.utils.DownloadUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
/**
 * @Class: Downloador
 * @Description: 任務(wù)下載器
 * @author: lling(www.cnblogs.com/liuling)
 * @Date: 2015/10/13
 */
public class Downloador {
 public static final String TAG = "Downloador";
 private static final int THREAD_POOL_SIZE = 9; //線程池大小為9
 private static final int THREAD_NUM = 3; //每個(gè)文件3個(gè)線程下載
 private static final int GET_LENGTH_SUCCESS = 1;
 public static final Executor THREAD_POOL_EXECUTOR = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
 private List<DownloadTask> tasks;
 private InnerHandler handler = new InnerHandler();
 private AppContent appContent; //待下載的應(yīng)用
 private long downloadLength; //下載過(guò)程中記錄已下載大小
 private long fileLength;
 private Context context;
 private String downloadPath;
 public Downloador(Context context, AppContent appContent) {
 this.context = context;
 this.appContent = appContent;
 this.downloadPath = DownloadUtils.getDownloadPath();
 }
 /**
 * 開(kāi)始下載
 */
 public void download() {
 if(TextUtils.isEmpty(downloadPath)) {
 Toast.makeText(context, "未找到SD卡", Toast.LENGTH_SHORT).show();
 return;
 }
 if(appContent == null) {
 throw new IllegalArgumentException("download content can not be null");
 }
 new Thread() {
 @Override
 public void run() {
 //獲取文件大小
 HttpClient client = new DefaultHttpClient();
 HttpGet request = new HttpGet(appContent.getUrl());
 HttpResponse response = null;
 try {
  response = client.execute(request);
  fileLength = response.getEntity().getContentLength();
 } catch (Exception e) {
  Log.e(TAG, e.getMessage());
 } finally {
  if (request != null) {
  request.abort();
  }
 }
 //計(jì)算出該文件已經(jīng)下載的總長(zhǎng)度
 List<DownloadInfo> lists = DownloadInfoDAO.getInstance(context.getApplicationContext())
  .getDownloadInfosByUrl(appContent.getUrl());
 for (DownloadInfo info : lists) {
  downloadLength += info.getDownloadLength();
 }
 //插入文件下載記錄到數(shù)據(jù)庫(kù)
 DownloadFileDAO.getInstance(context.getApplicationContext()).insertDownloadFile(appContent);
 Message.obtain(handler, GET_LENGTH_SUCCESS).sendToTarget();
 }
 }.start();
 }
 /**
 * 開(kāi)始創(chuàng)建AsyncTask下載
 */
 private void beginDownload() {
 Log.e(TAG, "beginDownload" + appContent.getUrl());
 appContent.setStatus(AppContent.Status.WAITING);
 long blockLength = fileLength / THREAD_NUM;
 for (int i = 0; i < THREAD_NUM; i++) {
 long beginPosition = i * blockLength;//每條線程下載的開(kāi)始位置
 long endPosition = (i + 1) * blockLength;//每條線程下載的結(jié)束位置
 if (i == (THREAD_NUM - 1)) {
 endPosition = fileLength;//如果整個(gè)文件的大小不為線程個(gè)數(shù)的整數(shù)倍,則最后一個(gè)線程的結(jié)束位置即為文件的總長(zhǎng)度
 }
 DownloadTask task = new DownloadTask(i, beginPosition, endPosition, this, context);
 task.executeOnExecutor(THREAD_POOL_EXECUTOR, appContent.getUrl());
 if(tasks == null) {
 tasks = new ArrayList<DownloadTask>();
 }
 tasks.add(task);
 }
 }
 /**
 * 暫停下載
 */
 public void pause() {
 for (DownloadTask task : tasks) {
 if (task != null && (task.getStatus() == AsyncTask.Status.RUNNING || !task.isCancelled())) {
 task.cancel(true);
 }
 }
 tasks.clear();
 appContent.setStatus(AppContent.Status.PAUSED);
 DownloadFileDAO.getInstance(context.getApplicationContext()).updateDownloadFile(appContent);
 }
 /**
 * 將已下載大小歸零
 */
 protected synchronized void resetDownloadLength() {
 this.downloadLength = 0;
 }
 /**
 * 添加已下載大小
 * 多線程訪問(wèn)需加鎖
 * @param size
 */
 protected synchronized void updateDownloadLength(long size){
 this.downloadLength += size;
 //通知更新界面
 int percent = (int)((float)downloadLength * 100 / (float)fileLength);
 appContent.setDownloadPercent(percent);
 if(percent == 100 || downloadLength == fileLength) {
 appContent.setDownloadPercent(100); //上面計(jì)算有時(shí)候會(huì)有點(diǎn)誤差,算到percent=99
 appContent.setStatus(AppContent.Status.FINISHED);
 DownloadFileDAO.getInstance(context.getApplicationContext()).updateDownloadFile(appContent);
 }
 Intent intent = new Intent(Constants.DOWNLOAD_MSG);
 if(appContent.getStatus() == AppContent.Status.WAITING) {
 appContent.setStatus(AppContent.Status.DOWNLOADING);
 }
 Bundle bundle = new Bundle();
 bundle.putParcelable("appContent", appContent);
 intent.putExtras(bundle);
 context.sendBroadcast(intent);
 }
 protected String getDownloadPath() {
 return downloadPath;
 }
 private class InnerHandler extends Handler {
 @Override
 public void handleMessage(Message msg) {
 switch (msg.what) {
 case GET_LENGTH_SUCCESS :
  beginDownload();
  break;
 }
 super.handleMessage(msg);
 }
 }
}

 2、DownloadTask類(lèi)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package com.bbk.lling.multitaskdownload.downloador;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import com.bbk.lling.multitaskdownload.beans.DownloadInfo;
import com.bbk.lling.multitaskdownload.db.DownloadInfoDAO;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.MalformedURLException;
/**
 * @Class: DownloadTask
 * @Description: 文件下載AsyncTask
 * @author: lling(www.cnblogs.com/liuling)
 * @Date: 2015/10/13
 */
public class DownloadTask extends AsyncTask<String, Integer , Long> {
 private static final String TAG = "DownloadTask";
 private int taskId;
 private long beginPosition;
 private long endPosition;
 private long downloadLength;
 private String url;
 private Downloador downloador;
 private DownloadInfoDAO downloadInfoDAO;
 public DownloadTask(int taskId, long beginPosition, long endPosition, Downloador downloador,
  Context context) {
 this.taskId = taskId;
 this.beginPosition = beginPosition;
 this.endPosition = endPosition;
 this.downloador = downloador;
 downloadInfoDAO = DownloadInfoDAO.getInstance(context.getApplicationContext());
 }
 @Override
 protected void onPreExecute() {
 Log.e(TAG, "onPreExecute");
 }
 @Override
 protected void onPostExecute(Long aLong) {
 Log.e(TAG, url + "taskId:" + taskId + "executed");
// downloador.updateDownloadInfo(null);
 }
 @Override
 protected void onProgressUpdate(Integer... values) {
 //通知downloador增加已下載大小
// downloador.updateDownloadLength(values[0]);
 }
 @Override
 protected void onCancelled() {
 Log.e(TAG, "onCancelled");
// downloador.updateDownloadInfo(null);
 }
 @Override
 protected Long doInBackground(String... params) {
 //這里加判斷的作用是:如果還處于等待就暫停了,運(yùn)行到這里已經(jīng)cancel了,就直接退出
 if(isCancelled()) {
 return null;
 }
 url = params[0];
 if(url == null) {
 return null;
 }
 HttpClient client = new DefaultHttpClient();
 HttpGet request = new HttpGet(url);
 HttpResponse response;
 InputStream is;
 RandomAccessFile fos = null;
 OutputStream output = null;
 DownloadInfo downloadInfo = null;
 try {
 //本地文件
 File file = new File(downloador.getDownloadPath() + File.separator + url.substring(url.lastIndexOf("/") + 1));
 //獲取之前下載保存的信息
 downloadInfo = downloadInfoDAO.getDownloadInfoByTaskIdAndUrl(taskId, url);
 //從之前結(jié)束的位置繼續(xù)下載
 //這里加了判斷file.exists(),判斷是否被用戶刪除了,如果文件沒(méi)有下載完,但是已經(jīng)被用戶刪除了,則重新下載
 if(file.exists() && downloadInfo != null) {
 if(downloadInfo.isDownloadSuccess() == 1) {
  //下載完成直接結(jié)束
  return null;
 }
 beginPosition = beginPosition + downloadInfo.getDownloadLength();
 downloadLength = downloadInfo.getDownloadLength();
 }
 if(!file.exists()) {
 //如果此task已經(jīng)下載完,但是文件被用戶刪除,則需要重新設(shè)置已下載長(zhǎng)度,重新下載
 downloador.resetDownloadLength();
 }
 //設(shè)置下載的數(shù)據(jù)位置beginPosition字節(jié)到endPosition字節(jié)
 Header header_size = new BasicHeader("Range", "bytes=" + beginPosition + "-" + endPosition);
 request.addHeader(header_size);
 //執(zhí)行請(qǐng)求獲取下載輸入流
 response = client.execute(request);
 is = response.getEntity().getContent();
 //創(chuàng)建文件輸出流
 fos = new RandomAccessFile(file, "rw");
 //從文件的size以后的位置開(kāi)始寫(xiě)入
 fos.seek(beginPosition);
 byte buffer [] = new byte[1024];
 int inputSize = -1;
 while((inputSize = is.read(buffer)) != -1) {
 fos.write(buffer, 0, inputSize);
 downloadLength += inputSize;
 downloador.updateDownloadLength(inputSize);
 //如果暫停了,需要將下載信息存入數(shù)據(jù)庫(kù)
 if (isCancelled()) {
  if(downloadInfo == null) {
  downloadInfo = new DownloadInfo();
  }
  downloadInfo.setUrl(url);
  downloadInfo.setDownloadLength(downloadLength);
  downloadInfo.setTaskId(taskId);
  downloadInfo.setDownloadSuccess(0);
  //保存下載信息到數(shù)據(jù)庫(kù)
  downloadInfoDAO.insertDownloadInfo(downloadInfo);
  return null;
 }
 }
 } catch (MalformedURLException e) {
 Log.e(TAG, e.getMessage());
 } catch (IOException e) {
 Log.e(TAG, e.getMessage());
 } finally{
 try{
 if (request != null) {
  request.abort();
 }
 if(output != null) {
  output.close();
 }
 if(fos != null) {
  fos.close();
 }
 } catch(Exception e) {
 e.printStackTrace();
 }
 }
 //執(zhí)行到這里,說(shuō)明該task已經(jīng)下載完了
 if(downloadInfo == null) {
 downloadInfo = new DownloadInfo();
 }
 downloadInfo.setUrl(url);
 downloadInfo.setDownloadLength(downloadLength);
 downloadInfo.setTaskId(taskId);
 downloadInfo.setDownloadSuccess(1);
 //保存下載信息到數(shù)據(jù)庫(kù)
 downloadInfoDAO.insertDownloadInfo(downloadInfo);
 return null;
 }
}

Downloador和DownloadTask只這個(gè)例子的核心代碼,下面是關(guān)于數(shù)據(jù)庫(kù)的,因?yàn)橐獙?shí)現(xiàn)斷點(diǎn)續(xù)傳必須要在暫停的時(shí)候?qū)⒚總€(gè)線程下載的位置記錄下來(lái),方便下次繼續(xù)下載時(shí)讀取。這里有兩個(gè)表,一個(gè)是存放每個(gè)文件的下載狀態(tài)的,一個(gè)是存放每個(gè)文件對(duì)應(yīng)的每個(gè)線程的下載狀態(tài)的。

  3、DBHelper

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.bbk.lling.multitaskdownload.db;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
 * @Class: DBHelper
 * @Description: 數(shù)據(jù)庫(kù)幫助類(lèi)
 * @author: lling(www.cnblogs.com/liuling)
 * @Date: 2015/10/14
 */
public class DBHelper extends SQLiteOpenHelper {
 public DBHelper(Context context) {
 super(context, "download.db", null, 1);
 }
 @Override
 public void onCreate(SQLiteDatabase db) {
 db.execSQL("create table download_info(_id INTEGER PRIMARY KEY AUTOINCREMENT, task_id INTEGER, "
 + "download_length INTEGER, url VARCHAR(255), is_success INTEGER)");
 db.execSQL("create table download_file(_id INTEGER PRIMARY KEY AUTOINCREMENT, app_name VARCHAR(255), "
 + "url VARCHAR(255), download_percent INTEGER, status INTEGER)");
 }
 @Override
 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
 }
}

4、DownloadFileDAO,文件下載狀態(tài)的數(shù)據(jù)庫(kù)操作類(lèi)

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

5、DownloadInfoDAO,每個(gè)線程對(duì)應(yīng)下載狀態(tài)的數(shù)據(jù)庫(kù)操作類(lèi)

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

具體的界面和使用代碼我就不貼代碼了,代碼有點(diǎn)多。需要的可以下載Demo的源碼看看。

  因?yàn)檫€沒(méi)有花太多時(shí)間去測(cè),里面難免會(huì)有些bug,如果大家發(fā)現(xiàn)什么問(wèn)題,歡迎留言探討,謝謝!  

源碼下載:https://github.com/liuling07/MultiTaskAndThreadDownload

原文鏈接:http://www.cnblogs.com/liuling/p/2015-10-16-01.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 午夜精品福利视频 | 国产免费成人在线 | 亚洲免费视 | 亚洲成人福利在线观看 | 免费看成年人网站 | 久久人人爽人人爽人人片av高清 | 久久国产在线观看 | 日日爱夜夜操 | 成人一级片毛片 | 72pao成人国产永久免费视频 | 色婷婷久久一区二区 | 亚洲视频在线网 | 国产一区二区二 | 免费一级欧美大片视频在线 | 中国久久久 | 欧美一级视频网站 | 国产高清成人久久 | 欧美精品一区二区中文字幕 | 91美女视频在线观看 | 久久激情国产 | 欧美日韩大片在线观看 | 久精品国产 | 色97色| 精品国产乱码久久久久久预案 | 成人不卡免费视频 | 国产伦久视频免费观看视频 | 免费观看三级毛片 | 日本爽快片100色毛片视频 | 色妇视频 | 日韩欧美精品电影 | 九色p | 成人精品aaaa网站 | 日韩av毛片免费观看 | sesee99| 成人免费精品视频 | 末成年女av片一区二区 | 欧美1区2区在线观看 | 欧美一级做a | 最新在线黄色网址 | 成人不卡| 中文字幕在线观看1 |