博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(Android小应用)在Android中实现多线程断点下载(连载一)
阅读量:2227 次
发布时间:2019-05-09

本文共 9288 字,大约阅读时间需要 30 分钟。

当我们从Internet中下载一个文件时,有的文件比较大,比如音乐或视频文件,下载的话需要比较长的时间,当我们在下载过程中,如果手机没电了或者其它原因,使当前的下载中断了,按照一般的程序,当下次下载又需要从新开始,这里我们来实现多纯程断点下载,当下载中断了,下次启动的时候还会接着下载,有点像我们的迅雷了……

首先呢,我们先不急着建Android应用,先建一个Java项目,测试一下下

然后在这个项目里面建一个测试用例

包都可以不填,因为只是测试,不是真正的应用,偷懒了……

OK,接着写代码

package   
junit.test;
import
java.io.ByteArrayOutputStream;
import
java.io.File;
import
java.io.FileOutputStream;
import
java.io.InputStream;
import
java.net.HttpURLConnection;
import
java.net.URL;
import
org.junit.Test;
public
class
InternetTest {
/**
* 读取输入流并返回数据 *
@param
input *
@return
*
@throws
Exception
*/
public
byte
[] readStream(InputStream input)
throws
Exception{
byte
[] buffer
=
new
byte
[
1024
]; ByteArrayOutputStream output
=
new
ByteArrayOutputStream();
int
len
=
-
1
;
while
((len
=
input.read(buffer))
!=-
1
){ output.write(buffer,
0
, len); } input.close(); output.close();
return
output.toByteArray(); }
/**
* 从网络上下载图片 *
@throws
Exception
*/
@Test
public
void
getImage()
throws
Exception{ String urlPath
=
"
http://photocdn.sohu.com/20110401/Img280097999.jpg
"
;
//
在网络上随便找一张图片的链接
URL url
=
new
URL(urlPath); HttpURLConnection conn
=
(HttpURLConnection) url.openConnection();
//
返回一个连接对象
conn.setRequestMethod(
"
GET
"
);
//
设置请求方式
conn.setConnectTimeout(
6
*
1000
);
//
设置连接超时,这里可以不用设置,但是在android应用中应该设置超时时间
if
(conn.getResponseCode()
==
200
) { InputStream input
=
conn.getInputStream();
byte
[] data
=
readStream(input); File file
=
new
File(
"
test.jpg
"
); FileOutputStream output
=
new
FileOutputStream(file); output.write(data); output.close(); } }
/**
* 得到网页html *
@throws
Exception
*/
@Test
public
void
getHtml()
throws
Exception{ String urlPath
=
"
http://www.baidu.com
"
; URL url
=
new
URL(urlPath); HttpURLConnection conn
=
(HttpURLConnection) url.openConnection(); conn.setRequestMethod(
"
GET
"
); conn.setConnectTimeout(
6
*
1000
);
if
(conn.getResponseCode()
==
200
) { InputStream input
=
conn.getInputStream();
byte
[] data
=
readStream(input); System.out.println(
new
String(data));
//
直接输出到控制台
} }}

然后测试,是否有预期的结果,如果有,继续下面,如果没有,再看看是不是哪儿错了

然后再建一个测试类,实现多线程下载,以下载一首mp3为例

package   
junit.test;
import
java.io.ByteArrayOutputStream;
import
java.io.File;
import
java.io.FileOutputStream;
import
java.io.IOException;
import
java.io.InputStream;
import
java.io.RandomAccessFile;
import
java.net.HttpURLConnection;
import
java.net.MalformedURLException;
import
java.net.ProtocolException;
import
java.net.URL;
import
org.junit.Test;
public
class
DownloaderTest {
/**
* 读取输入流并返回数据 *
@param
input *
@return
*
@throws
Exception
*/
public
byte
[] readStream(InputStream input)
throws
Exception { ByteArrayOutputStream output
=
new
ByteArrayOutputStream();
byte
[] buffer
=
new
byte
[
1024
];
int
len
=
-
1
;
while
((len
=
input.read(buffer))
!=
-
1
) { output.write(buffer,
0
, len); } input.close(); output.close();
return
output.toByteArray(); } @Test
public
void
downloader()
throws
Exception { String urlPath
=
"
http://dl.toofiles.com/vaaoje/audios/qbd.mp3
"
; URL url
=
new
URL(urlPath); HttpURLConnection conn
=
(HttpURLConnection) url.openConnection(); conn.setRequestMethod(
"
GET
"
);
int
threadsize
=
3
;
//
定义线程数
int
filesize
=
conn.getContentLength();
//
获取文件大小
int
block
=
filesize
/
threadsize
+
1
;
//
每条线程下载的数量
conn.disconnect(); File file
=
new
File(
"
千百度.mp3
"
); RandomAccessFile randfile
=
new
RandomAccessFile(file,
"
rw
"
);
//
RandomAccessFile可以指定从文件的什么位置写入数据
for
(
int
i
=
0
;i
<
threadsize;i
++
){
int
startposition
=
i
*
block;
//
记录每条线程的开始位置
RandomAccessFile threadfile
=
new
RandomAccessFile(file,
"
rw
"
); threadfile.seek(startposition);
//
从文件的什么位置开始写入
new
Thread(
new
DownloadThread(i,url,startposition,threadfile,block)).start(); }
/*
* 设置一个标志,当输入q的时候停止主线程
*/
byte
b[]
=
new
byte
[
1
]; System.in.read(b);
while
(
!
(
'
q
'
==
b[
0
])){ Thread.sleep(
3
*
1000
); } }
private
class
DownloadThread
implements
Runnable{
private
int
id ;
private
URL url;
private
int
startposition;
private
RandomAccessFile threadfile;
private
int
block;
public
DownloadThread(
int
id ,URL url,
int
startposition,RandomAccessFile threadfile,
int
block){
this
.id
=
id;
this
.url
=
url;
this
.startposition
=
startposition;
this
.threadfile
=
threadfile;
this
.block
=
block; } @Override
public
void
run() {
//
TODO Auto-generated method stub
try
{ HttpURLConnection conn
=
(HttpURLConnection)url.openConnection(); conn.setRequestMethod(
"
GET
"
); conn.setRequestProperty(
"
Range
"
,
"
bytes=
"
+
startposition
+
"
-
"
); conn.setConnectTimeout(
6
*
1000
); InputStream input
=
conn.getInputStream();
byte
[] buffer
=
new
byte
[
1024
];
int
len
=
-
1
;
int
readfilesize
=
0
;
//
记录下载的文件大小
while
(readfilesize
<
block
&&
((len
=
input.read(buffer))
!=
-
1
)) { threadfile.write(buffer,
0
, len); readfilesize
+=
len;
//
累计下载的文件大小
} threadfile.close(); conn.disconnect(); System.out.println((
this
.id
+
1
)
+
"
线程下载完成
"
); }
catch
(IOException e) {
//
TODO Auto-generated catch block
e.printStackTrace(); } } }}

运行此测试类,如果没有异常抛出的话就成功了……

多线程下载的核心代码已经完成,下面结合到android应用中,我们还得用到SQLite知识,要实现多线程下载,当中断的时候,我们系统会记录一个下载位置,我们把它保存在数据库中,第二次运行的时候再从数据库中读取出来,假设大家都有SQLite方面的知识……

接下来应该建Android项目了

连载中……

转载地址:http://rqhfb.baihongyu.com/

你可能感兴趣的文章
决策树的python实现
查看>>
Sklearn 快速入门
查看>>
了解 Sklearn 的数据集
查看>>
用ARIMA模型做需求预测
查看>>
推荐系统
查看>>
TensorFlow-11-策略网络
查看>>
浅谈 GBDT
查看>>
如何选择优化器 optimizer
查看>>
一文了解强化学习
查看>>
CART 分类与回归树
查看>>
seq2seq 的 keras 实现
查看>>
seq2seq 入门
查看>>
什么是 Dropout
查看>>
用 LSTM 做时间序列预测的一个小例子
查看>>
用 LSTM 来做一个分类小问题
查看>>
详解 LSTM
查看>>
按时间轴简述九大卷积神经网络
查看>>
详解循环神经网络(Recurrent Neural Network)
查看>>
为什么要用交叉验证
查看>>
用学习曲线 learning curve 来判别过拟合问题
查看>>