okhttp-OkGo
okhttp-OkGo copied to clipboard
关于支持不可断点下载的资源的几条建议
1.本库对于不可断点下载的资源支持很差,如果常规的下载会报异常 breakpoint file has expired 。 2.通过手动设置 task.progress.totalSize 后可以下载不可断点下载资源,但是强杀进程再次下载时文件全量下载,追加到上次下载了部分的文件后。导致下载的文件比实际文件要大,进度也会超过100%。假如手动设置的长度和文件实际长度不一致,还是会下载失败 3.对于不可断点下载的资源,而又不知道他的长度时,那就下载不了了。产品这时候跳出去说,你看浏览器都可以下载啊,你无言以对
我下载本库后做了一些 修改,在DownloadTask 的run方法中增加了资源是否支持断点下载的判断,再分情况处理下,基本解决了上述问题。但是本人很菜,修改的感觉不是健壮,希望作者大牛可以把这个优化下。
怎么修改的?分享一下呗
怎么修改的?分享一下呗
以下是DownloadTask 中run 方法的修改
@Override public void run() { //check breakpoint long startPosition = progress.currentSize; if (startPosition < 0) { startPosition = 0; } if (startPosition > 0) { if (!TextUtils.isEmpty(progress.filePath)) { File file = new File(progress.filePath); if (!file.exists()) { startPosition = 0; } } }
//request network from startPosition
Response response;
try {
Request<?, ? extends Request> request = progress.request;
request.headers(HttpHeaders.HEAD_KEY_RANGE, "bytes=" + startPosition + "-");
response = request.execute();
} catch (IOException e) {
postOnError(progress, e);
return;
}
//check network data
int code = response.code();
if (code == 404 || code >= 500) {
postOnError(progress, HttpException.NET_ERROR());
return;
}
ResponseBody body = response.body();
if (body == null) {
postOnError(progress, new HttpException("response body is null"));
return;
}
Headers headers = response.headers();
if (headers != null) {
String length = headers.get("Content-Length");
String acceptRange = headers.get("Accept-Ranges");
if (!TextUtils.isEmpty(length) && Long.parseLong(length) > 0 && "bytes".equals(acceptRange)) {
supportBP = true;
}
}
//不支持断点的 会全量下载,所以先删除以前下载的部分
if (!supportBP) {
if (!TextUtils.isEmpty(progress.filePath)) {
File file = new File(progress.filePath);
if (file.exists()) {
IOUtils.delFileOrFolder(file);
startPosition = 0;
}
}
}
if (progress.totalSize == -1) {
if (supportBP) {
progress.totalSize = body.contentLength();
} else {
progress.totalSize = totalLength;
}
}
//模糊进度
if (progress.totalSize == 0) {
progress.indeterminate = true;
}
//create filename
String fileName = progress.fileName;
if (TextUtils.isEmpty(fileName)) {
fileName = HttpUtils.getNetFileName(response, progress.url);
progress.fileName = fileName;
}
if (!IOUtils.createFolder(progress.folder)) {
postOnError(progress, StorageException.NOT_AVAILABLE());
return;
}
//create file
File file;
if (TextUtils.isEmpty(progress.filePath)) {
file = new File(progress.folder, fileName);
progress.filePath = file.getAbsolutePath();
} else {
file = new File(progress.filePath);
}
if (startPosition > 0 && !file.exists()) {
// postOnError(progress, OkGoException.BREAKPOINT_EXPIRED()); restart(); return; }
// if (startPosition > progress.totalSize) { // postOnError(progress, OkGoException.BREAKPOINT_EXPIRED()); // return; // } if (startPosition == 0 && file.exists()) { IOUtils.delFileOrFolder(file); } if (startPosition == progress.totalSize && startPosition > 0) { if (file.exists() && startPosition == file.length()) { postOnFinish(progress, file); return; } else { postOnError(progress, OkGoException.BREAKPOINT_EXPIRED()); return; } }
//start downloading
RandomAccessFile randomAccessFile;
try {
randomAccessFile = new RandomAccessFile(file, "rw");
randomAccessFile.seek(startPosition);
progress.currentSize = startPosition;
} catch (Exception e) {
postOnError(progress, e);
return;
}
try {
DownloadManager.getInstance().replace(progress);
download(body.byteStream(), randomAccessFile, progress);
} catch (IOException e) {
postOnError(progress, e);
return;
}
//check finish status
if (progress.status == Progress.PAUSE) {
postPause(progress);
} else if (progress.status == Progress.LOADING) {
if (supportBP) {
if (file.length() == progress.totalSize) {
postOnFinish(progress, file);
} else {
postOnError(progress, OkGoException.BREAKPOINT_EXPIRED());
}
} else {
postOnFinish(progress, file);
}
} else {
postOnError(progress, OkGoException.UNKNOWN());
}
}