- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Android 使用AsyncTask实现多任务多线程断点续传下载由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
这篇博客是AsyncTask下载系列的最后一篇文章,前面写了关于断点续传的和多线程下载的博客,这篇是在前两篇的基础上面实现的,有兴趣的可以去看下.
1、AsyncTask实现断点续传 。
2、AsyncTask实现多线程断点续传 。
这里模拟应用市场app下载实现了一个Demo,因为只有一个界面,所以没有将下载放到Service中,而是直接在Activity中创建。在正式的项目中,下载都是放到Service中,然后通过BroadCast通知界面更新进度.
上代码之前,先看下demo的运行效果图吧.
下面我们看代码,这里每一个文件的下载定义一个Downloador来管理下载该文件的所有线程(暂停、下载等)。Downloador创建3个DownloadTask(这里定义每个文件分配3个线程下载)来下载该文件特定的起止位置。这里要通过文件的大小来计算每个线程所下载的起止位置,详细可以参考《AsyncTask实现多线程断点续传》.
1、Downloador类 。
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: 任务下载器
* @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
;
//每个文件3个线程下载
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;
//待下载的应用
private
long
downloadLength;
//下载过程中记录已下载大小
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();
}
/**
* 开始下载
*/
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();
}
}
//计算出该文件已经下载的总长度
List<DownloadInfo> lists = DownloadInfoDAO.getInstance(context.getApplicationContext())
.getDownloadInfosByUrl(appContent.getUrl());
for
(DownloadInfo info : lists) {
downloadLength += info.getDownloadLength();
}
//插入文件下载记录到数据库
DownloadFileDAO.getInstance(context.getApplicationContext()).insertDownloadFile(appContent);
Message.obtain(handler, GET_LENGTH_SUCCESS).sendToTarget();
}
}.start();
}
/**
* 开始创建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;
//每条线程下载的开始位置
long
endPosition = (i +
1
) * blockLength;
//每条线程下载的结束位置
if
(i == (THREAD_NUM -
1
)) {
endPosition = fileLength;
//如果整个文件的大小不为线程个数的整数倍,则最后一个线程的结束位置即为文件的总长度
}
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
;
}
/**
* 添加已下载大小
* 多线程访问需加锁
* @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
);
//上面计算有时候会有点误差,算到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类 。
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) {
//这里加判断的作用是:如果还处于等待就暂停了,运行到这里已经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);
//从之前结束的位置继续下载
//这里加了判断file.exists(),判断是否被用户删除了,如果文件没有下载完,但是已经被用户删除了,则重新下载
if
(file.exists() && downloadInfo !=
null
) {
if
(downloadInfo.isDownloadSuccess() ==
1
) {
//下载完成直接结束
return
null
;
}
beginPosition = beginPosition + downloadInfo.getDownloadLength();
downloadLength = downloadInfo.getDownloadLength();
}
if
(!file.exists()) {
//如果此task已经下载完,但是文件被用户删除,则需要重新设置已下载长度,重新下载
downloador.resetDownloadLength();
}
//设置下载的数据位置beginPosition字节到endPosition字节
Header header_size =
new
BasicHeader(
"Range"
,
"bytes="
+ beginPosition +
"-"
+ endPosition);
request.addHeader(header_size);
//执行请求获取下载输入流
response = client.execute(request);
is = response.getEntity().getContent();
//创建文件输出流
fos =
new
RandomAccessFile(file,
"rw"
);
//从文件的size以后的位置开始写入
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);
//如果暂停了,需要将下载信息存入数据库
if
(isCancelled()) {
if
(downloadInfo ==
null
) {
downloadInfo =
new
DownloadInfo();
}
downloadInfo.setUrl(url);
downloadInfo.setDownloadLength(downloadLength);
downloadInfo.setTaskId(taskId);
downloadInfo.setDownloadSuccess(
0
);
//保存下载信息到数据库
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();
}
}
//执行到这里,说明该task已经下载完了
if
(downloadInfo ==
null
) {
downloadInfo =
new
DownloadInfo();
}
downloadInfo.setUrl(url);
downloadInfo.setDownloadLength(downloadLength);
downloadInfo.setTaskId(taskId);
downloadInfo.setDownloadSuccess(
1
);
//保存下载信息到数据库
downloadInfoDAO.insertDownloadInfo(downloadInfo);
return
null
;
}
}
|
Downloador和DownloadTask只这个例子的核心代码,下面是关于数据库的,因为要实现断点续传必须要在暂停的时候将每个线程下载的位置记录下来,方便下次继续下载时读取。这里有两个表,一个是存放每个文件的下载状态的,一个是存放每个文件对应的每个线程的下载状态的.
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: 数据库帮助类
* @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,文件下载状态的数据库操作类 。
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: 每个文件下载状态记录的数据库操作类
* @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;
}
/**
* 获取数据库连接
* @return
*/
public
SQLiteDatabase getConnection() {
SQLiteDatabase sqliteDatabase =
null
;
try
{
sqliteDatabase=
new
DBHelper(context).getReadableDatabase();
}
catch
(Exception e) {
Log.e(TAG, e.getMessage());
}
return
sqliteDatabase;
}
/**
* 插入数据
* @param appContent
*/
public
void
insertDownloadFile(AppContent appContent) {
if
(appContent ==
null
) {
return
;
}
//如果本地已经存在,直接修改
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();
}
}
}
/**
* 根据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;
}
/**
* 根据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,每个线程对应下载状态的数据库操作类 。
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: 每个单独线程下载信息记录的数据库操作类
* @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;
}
/**
* 获取数据库连接
* @return
*/
public
SQLiteDatabase getConnection() {
SQLiteDatabase sqliteDatabase =
null
;
try
{
sqliteDatabase=
new
DBHelper(context).getReadableDatabase();
}
catch
(Exception e) {
Log.e(TAG, e.getMessage());
}
return
sqliteDatabase;
}
/**
* 插入数据
* @param downloadInfo
*/
public
void
insertDownloadInfo(DownloadInfo downloadInfo) {
if
(downloadInfo ==
null
) {
return
;
}
//如果本地已经存在,直接修改
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;
}
/**
* 根据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();
}
}
}
}
|
具体的界面和使用代码我就不贴代码了,代码有点多。需要的可以下载Demo的源码看看.
因为还没有花太多时间去测,里面难免会有些bug,如果大家发现什么问题,欢迎留言探讨,谢谢! 。
源码下载:https://github.com/liuling07/MultiTaskAndThreadDownload 。
原文链接:http://www.cnblogs.com/liuling/p/2015-10-16-01.html 。
最后此篇关于Android 使用AsyncTask实现多任务多线程断点续传下载的文章就讲到这里了,如果你想了解更多关于Android 使用AsyncTask实现多任务多线程断点续传下载的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我有以下正则表达式 /[a-zA-Z0-9_-]/ 当字符串只包含从 a 到z 大小写、数字、_ 和 -。 我的代码有什么问题? 能否请您向我提供一个简短的解释和有关如何修复它的代码示例? //var
我是一名优秀的程序员,十分优秀!