(一)CommonLibrary之Retrofit+RxJava网络请求封装
上一篇大概说了下CommonLibrary的Retrofit+RxJava网络请求封装,这篇说一下关于文件下载的处理。
同样先看调用方式
使用的QQ下载地址作为测试
NeedWifiOperate.getDefault().networkTypeShouldBeWifi(new DefaultNetworkTypeCallBack(this) {
@Override
public void wifi(int netType) {
downloadFile();
}
}.setDialogOperateListener(new DialogOperateAdapter() {
@Override
public void positive(Context context, Dialog dialog) {
downloadFile();
}
}));
/**
* 暂停下载后重新下载已做了文件的追加,但文件路径必须一致,所以通常可以将url的md5做文件名
* 在重新下载时进度是未下载部分的百分比进度,所以你需要自行计算,计算方式为
* 重新开始时进度 = 已下载 / (已下载 + 未下载(重新下载时onStart会回传)) * 100%
* 重新下载时进度 = (已下载 + progress * 未下载) / (已下载 + 未下载(重新下载时onStart会回传)) * 100%
* <p>
* tips: 怎么判断是重新下载? 文件存在且file.length()大于0
* <p>
* 怎么获取已下载字节数? file.length()
*/
private void downloadFile() {
String downloadUrl = "http://gdown.baidu.com/data/wisegame/13095bef5973a891/QQ_786.apk";
File file = new File(CommonApplication.context.getCacheDir(), MD5Utils.MD5(downloadUrl) + ".apk");
LogUtils.e("DownloadFile: " + file.length());
DownloadFile downloadFile = new DownloadFile(downloadUrl, file.length(), file, new ChangeViewWithProgressListener(tvExample));
NetworkHelper.getDefault().download(mView, downloadFile, new FileCallBack() {
@Override
public void downloadSuccess(File file) {
mView.downloadFileSuccess(file);
}
@Override
public void downloadFail(Throwable e) {
mView.downloadFileFail(e);
}
});
}
前面一堆杂七杂八的操作暂时不说,只是一些辅助性的功能,主要还是downloadFile()这个方法,使用方式也很简单对吧,在整个里面已经处理了进度回调,断点下载,网络中断,提升用户体验还封装有网速检测工具,你可以选择使用。暂停下载需要你自己显示调用了,其实需要你们做的就两步
一、 构造下载文件
二、 发起下载请求
开始逐步说明
构造下载文件
我使用了一个对象封装下载需要的信息,这个对象长这样
//其中的get,set方法就不陈列在此了,没什么意义
public class DownloadFile {
private String url;
private File file;
private long start;
private ProgressListener listener;
public DownloadFile(String url, File file) {
this(url, 0, file, null);
}
public DownloadFile(String url, File file, ProgressListener listener) {
this(url, 0, file, listener);
}
public DownloadFile(String url, long start, File file, ProgressListener listener) {
this.url = url;
this.start = start;
this.file = file;
this.listener = listener;
}
}
看参数名字就能大概猜出来了
url -> 文件的下载地址
file -> 下载到本地的路径
start-> 断点下载的起始下载点
listener -> 下载进度
前三个都很容易就构建好了,最后一个下载进度就有点讲究了。先看看这个进度的树状关系
首先封装了一个将进度在主线程回调的listener,如果你要在主线程中自己处理进度,使用这个就OK了,里面其实就一个Handler做线程切换,没啥好说的。下面还有一个ChangeViewWithProgressListener,这个从名字就能看出来,这是一个可以随着进度更新View的的进度监听器,如果你需要一个View随着下载进度改变的话,这个Listener就能完美帮你完成。在构造这个Listener时需要传入一个IViewProgressEvent,所以你需要把随着进度改变的View实现此接口,然后完成对应的逻辑就可以了。第一步就完成了。
发起下载请求
NetworkHelper.getDefault().download(mView, downloadFile, new FileCallBack() {
@Override
public void downloadSuccess(File file) {
mView.downloadFileSuccess(file);
}
@Override
public void downloadFail(Throwable e) {
mView.downloadFileFail(e);
}
});
这样就发起请求了,然后在回调中处理对应的逻辑就OK了,在此只讲使用方式,更多代码请看[github]
暂停下载
在IViewProgressEvent回调里会回传请求的url,将此url保存起来,然后在需要暂停的地方调用DownloadObservableManager.getInstance().stopObserver(url);
即可暂停下载,调用后会回调cancel()方法,cancel里会回传已下载的总字节数,在此方法里做暂停后的操作。
网速检测
网速检测在network包下提供了一个NetworkSpeed类,在实例化该类时提供一个网速更新回调接口OnNetworkSpeedUpdateListener
即可,回调参数即为网速,在需要使用的地方显示调用startShowNetSpeed()
,另外注意:需要显示调用stopShowNetSpeed()
停止观测,谨防内存泄漏,一般在不需要的时候或者在onDestroy()里调用