您的位置:首页 > 移动开发 > Android开发

android下载的断点续传的功能的实现

2016-08-29 15:02 218 查看
前一篇博客介绍了android的多线程下载:

http://blog.csdn.net/whsdu929/article/details/52351807

下面来介绍一下下载过程中断点续传功能的实现。所谓的断点续传就是可以在下载过程中随时暂停下载,恢复下载时会从上次中断的地方继续下载,而不是从头开始。

断点续传的原理是:每次暂停下载时,记录保存每个线程当前下载到的位置,恢复下载时直接找到这个位置开始继续下载。

完整代码:

public class MainActivity extends ActionBarActivity {

public static final String TEST_URL = "http://gdown.baidu.com/data/wisegame/e59f42264a98b05e/WeChat_861.apk";

private Button btn;

private boolean mIsDownloading = false;

private List<HashMap<String, Integer>> mDownloadInfoList;

private URL url;

private File file;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

mDownloadInfoList = new ArrayList<>();

btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mIsDownloading){
mIsDownloading = false;
btn.setText("开始下载");
return;
}
mIsDownloading = true;
btn.setText("暂停下载");
if(mDownloadInfoList.size() == 0){
new Thread() {
@Override
public void run() {
try {
url = new URL(TEST_URL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727)");

String fileName = TEST_URL.substring(TEST_URL.lastIndexOf("/") + 1);
file = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), fileName);
int totalLength = conn.getContentLength();
int subLength = totalLength / 3;

for(int i = 0; i < 3; i++){
int start = i * subLength;
int end = (i+1) * subLength - 1;
if(i == 2){
end = totalLength;
}
HashMap<String, Integer> hashMap = new HashMap<>();
hashMap.put("start", start);
hashMap.put("end", end);
hashMap.put("finished", 0);
mDownloadInfoList.add(hashMap);
new DownloadThread(i, start, end, file, url).start();
}

} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}else{
for(int i = 0; i < 3; i++){
HashMap<String, Integer> hashMap = mDownloadInfoList.get(i);
int start = hashMap.get("start");
int end = hashMap.get("end");
int finished = hashMap.get("finished");
new DownloadThread(i, start + finished, end, file, url).start();
}
}
}
});
}

class DownloadThread extends Thread{

int threadId;
int start;
int end;
File file;
URL url;

int currLength = 0;
int totalLength;

public DownloadThread(int threadId, int start, int end, File file, URL url){
this.threadId = threadId;
this.start = start;
this.end = end;
this.file = file;
this.url = url;

totalLength = end - start + 1;
}

@Override
public void run() {
try {
if(start > end){
return;
}
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727)");
conn.setRequestProperty("Range", "bytes=" + start + "-" + end);

RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
randomAccessFile.seek(start);

HashMap<String, Integer> hashMap = mDownloadInfoList.get(threadId);
InputStream is = conn.getInputStream();
byte[] buf = new byte[1024 * 1024];
int len;
while((len = is.read(buf)) != -1 && mIsDownloading){
currLength += len;
hashMap.put("finished", currLength);
randomAccessFile.write(buf, 0, len);
}

is.close();
randomAccessFile.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息