DownloadFile
Android OkHttp 下载多个文件 断点下载
介绍
demo的主要逻辑是,利用okhttp 和 RxJava 在子线程中下载文件,通关观察者模式监听下载的进度,再回调到主线程中,然后利用EventBus 通知页面刷新,更新进度。
step1 导入依赖库
// OKHttp RxJava
implementation 'com.squareup.okhttp3:okhttp:3.6.0'
implementation 'io.reactivex.rxjava2:rxjava:2.1.3'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
// eventbus
implementation 'org.greenrobot:eventbus:3.0.0'
implementation 'com.android.support:recyclerview-v7:27.1.1'
implementation 'com.google.code.gson:gson:2.8.1'
//数据保存
implementation 'org.greenrobot:greendao:3.2.2'
step 2 定义下载bean
```Java DownloadInfo
step 3 DownLoadService 开启一个服务,进行删除,下载,暂停,等待等操作
step 4 下载管理类 也是主要的内容 (DownloadManager)具体的数据保存方法
public void download(final DownloadInfo downloadInfo) {
List<DownloadInfo> list = MyApplication.getInstances().getDaoSession().loadAll(DownloadInfo.class);
downWait.clear();
downWait = list;
if (currentDownInfo != null) pauseDownload(currentDownInfo, true);
if (downCalls.containsKey(downloadInfo.getUrl())) downCalls.remove(downloadInfo.getUrl());
Observable.just(downloadInfo.getUrl())
.filter(new Predicate<String>() { // 过滤 call的map中已经有了,就证明正在下载,则这次不下载
@Override
public boolean test(String s) {
boolean flag = downCalls.containsKey(s);
if (flag) {
// 如果已经在下载,并且不是暂停的数据,查找下一个文件进行下载
downNext();
return false;
} else {
// 判断如果正在下载的个数达到最大限制,存到等下下载列表中
return true;
}
}
})
.flatMap(new Function<String, ObservableSource<?>>() { // 生成 DownloadInfo
@Override
public ObservableSource<?> apply(String s) {
return Observable.just(createDownInfo(downloadInfo));
}
})
.map(new Function<Object, DownloadInfo>() { // 如果已经下载,重新命名
@Override
public DownloadInfo apply(Object o) {
return getRealFileName((DownloadInfo) o);
}
})
.flatMap(new Function<DownloadInfo, ObservableSource<DownloadInfo>>() { // 下载
@Override
public ObservableSource<DownloadInfo> apply(DownloadInfo downloadInfo) {
currentDownInfo = downloadInfo;
return Observable.create(new DownloadSubscribe(downloadInfo));
}
})
.observeOn(AndroidSchedulers.mainThread()) // 在主线程中回调
.subscribeOn(Schedulers.io()) // 在子线程中执行
.subscribe(new DownloadLimitObserver()); // 添加观察者,监听下载进度
}
这里用到的是Rxjava,第一步filter,过滤下载,已经下载的url再点击下载是不会另起下载任务的;第二步flatMap,通过url生成Bean类,这个按需求来设计,也可以直接传一个Bean进来也是可以的;第三步map,如果这个文件已经下载了,再次下载重新命名文件,这也是根据需求改变,如果下载过的文件不需要下载,这就可以省了;第四步flatMap,去下载具体去看下载方法;剩下的就是切换线程和添加观察者了。
step4 观察者
public class DownloadObserver implements Observer<DownloadInfo> {
public Disposable d;//可以用于取消注册的监听者
public DownloadInfo downloadInfo;
@Override
public void onSubscribe(Disposable d) {
this.d = d;
}
@Override
public void onNext(DownloadInfo value) {
this.downloadInfo = value;
downloadInfo.setDownloadStatus(DownloadInfo.DOWNLOAD);
EventBus.getDefault().post(downloadInfo);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
if (downloadInfo != null){
downloadInfo.setDownloadStatus(DownloadInfo.DOWNLOAD_OVER);
EventBus.getDefault().post(downloadInfo);
}
}
}
这里是用到EventBus来通知页面刷新