学习于:http://blog.csdn.net/sk719887916/article/details/51988507
所谓断点下载就是从暂停的地方重新开始下载:
下载过程中,点击暂停按钮时,会记录一个断点(就是已经下载的文件大小),恢复下载时通过添加请求头实现从断点位置继续下载。range:"bytes=" + length + "-"
;length
表示断点位置,初始时length = 0
,然后下载的数据拼接到第一次下载的文件的后面组成一个文件。
API
public interface ApiService {
/*断点下载接口*/
@Streaming/*大文件需要加入这个判断,防止下载过程中写入到内存中*/
@GET
Flowable<ResponseBody> download(@Header("RANGE") String start, @Url String url);
}
下载
//暂停下载
public void cancel(View view) {
mSubscribe.dispose();
}
//开始下载
public void load(View view) {
mFile = DownLoadManager.getFutureStudioIconFile();
if (mFile != null) {
length = mFile.length();
}
Log.d(TAG, "请求下载的初始位置:" + length);
mSubscribe = RetrofitClient.getInstance(getApplication()).getApiService()
.download("bytes=" + length + "-", url)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.map(new Function<ResponseBody, Boolean>() {
@Override
public Boolean apply(@NonNull ResponseBody responseBody) throws Exception {
return DownLoadManager.writeFile(getApplication(), responseBody, mProgressBar);
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Boolean>() {
@Override
public void accept(@NonNull Boolean aBoolean) throws Exception {
}
});
}
文件写入的工具类
public class DownLoadManager {
private static final String TAG = "DownLoadManager";
private static String APK_CONTENTTYPE = "application/vnd.android.package-archive";
private static String PNG_CONTENTTYPE = "image/png";
private static String JPG_CONTENTTYPE = "image/jpg";
private static String MP4_CONTENTTYPE = "video/mp4";
private static String fileSuffix = "";
private static File sFutureStudioIconFile;
private static long sFileSize;
private static String fileName = "whstywh";
public static String getFileName() {
return fileName;
}
public static File getFutureStudioIconFile() {
return sFutureStudioIconFile;
}
public static boolean writeFile(Context context, ResponseBody body, ProgressBar progressBar) {
Log.d(TAG, "contentType:>>>>" + body.contentType().toString());
String type = body.contentType().toString();
if (type.equals(APK_CONTENTTYPE)) {
fileSuffix = ".apk";
} else if (type.equals(PNG_CONTENTTYPE)) {
fileSuffix = ".png";
} else if (type.equals(JPG_CONTENTTYPE)) {
fileSuffix = ".jpg";
} else if (type.equals(MP4_CONTENTTYPE)) {
fileSuffix = ".mp4";
}
String sPath = Environment.getExternalStorageDirectory() + File.separator + fileName + fileSuffix;
Log.d(TAG, "path:>>>>" + sPath);
try {
// todo change the file location/name according to your needs
sFutureStudioIconFile = new File(sPath);
InputStream inputStream = null;
OutputStream outputStream = null;
try {
byte[] fileReader = new byte[4096];
//需要下载的文件总长度
if (sFileSize == 0) {
sFileSize = body.contentLength();
}
//已经下载的文件长度
long fileSizeDownloaded = sFutureStudioIconFile.length();
inputStream = body.byteStream();
outputStream = new FileOutputStream(sFutureStudioIconFile, true);
progressBar.setMax((int) sFileSize);
while (true) {
int read = inputStream.read(fileReader);
if (read == -1) {
break;
}
outputStream.write(fileReader, 0, read);
fileSizeDownloaded += read;
progressBar.setProgress((int) fileSizeDownloaded);
Log.d(TAG, "file download: " + fileSizeDownloaded + " of " + sFileSize);
}
outputStream.flush()
return true;
} catch (IOException e) {
return false;
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
} catch (IOException e) {
return false;
}
}
}
对于retrofit的学习才刚刚开始!
retrofit :入门
retrofit :Json数据缓存
retrofit :文件断点下载