本文将直接使用 RxHttp库 实现文件上传、下载、断点下载、进度的监听,不对RxHttp做过多讲解,如果对RxHttp不了解,请移步
RxHttp 一条链发送请求,新一代Http请求神器(一)
RxHttp 一条链发送请求之强大的数据解析功能(二)
RxHttp 一条链发送请求之强大的Param类(三)
RxHttp 一条链发送请求之注解处理器 Generated API(四)
本文目的在于让更多的读者知道RxHttp库,如果您已阅读上面4篇文章,本文可直接跳过,感谢你的支持。:pray::pray:。
RxHttp.postForm("http://...") //发送Form表单形式的Post请求 .add("key", "value") .add("file1", new File("xxx/1.png")) //添加file对象 .add("file2", new File("xxx/2.png")) .from() //from操作符,是异步操作 .as(RxLife.asOnMain(this)) //感知生命周期,并在主线程回调 .subscribe(s -> { //上传成功,拿到Http返回值,这里返回值为String类型 }, throwable -> { //上传失败 }); 复制代码
注:
如果需要对Http的返回值做解析,可在使用 from
操作符时,传入一个解析器 Parser
带进度上传
使用 uploadProgress
操作符,并结合 doOnNext
、 filter
、 map
即可
RxHttp.postForm("http://www.......") //发送Form表单形式的Post请求 .add("file1", new File("xxx/1.png")) .add("file2", new File("xxx/2.png")) .add("key1", "value1")//添加参数,非必须 .add("key2", "value2")//添加参数,非必须 .addHeader("versionCode", "100") //添加请求头,非必须 .uploadProgress() //注:如果需要监听上传进度,使用uploadProgress操作符 .observeOn(AndroidSchedulers.mainThread()) //主线程回调 .doOnNext(progress -> { //上传进度回调,0-100,仅在进度有更新时才会回调,最多回调101次,最后一次回调Http执行结果 int currentProgress = progress.getProgress(); //当前进度 0-100 long currentSize = progress.getCurrentSize(); //当前已上传的字节大小 long totalSize = progress.getTotalSize(); //要上传的总字节大小 String result = progress.getResult(); //Http执行结果,最后一次回调才有内容 }) .filter(Progress::isCompleted)//过滤事件,上传完成,才继续往下走 .map(Progress::getResult) //到这,说明上传完成,拿到Http返回结果并继续往下走 .as(RxLife.as(this)) //感知生命周期 .subscribe(s -> { //s为String类型,由SimpleParser类里面的泛型决定的 //上传成功,处理相关逻辑 }, throwable -> { //上传失败,处理相关逻辑 }); 复制代码
注:
如果需要对Http的返回值做解析,可在使用 uploadProgress
操作符时,传入一个解析器 Parser
//文件存储路径 String destPath = getExternalCacheDir() + "/" + System.currentTimeMillis() + ".apk"; RxHttp.get("http://update.9158.com/miaolive/Miaolive.apk") .download(destPath) //注意这里使用download操作符,并传入本地路径 .as(RxLife.asOnMain(this)) //感知生命周期,并在主线程回调 .subscribe(s -> { //下载成功,回调文件下载路径 }, throwable -> { //下载失败 }); 复制代码
带进度下载
使用 downloadProgress
操作符,并结合 doOnNext
、 filter
、 map
即可
//文件存储路径 String destPath = getExternalCacheDir() + "/" + System.currentTimeMillis() + ".apk"; RxHttp.get("http://update.9158.com/miaolive/Miaolive.apk") .downloadProgress(destPath) //注:如果需要监听下载进度,使用downloadProgress操作符 .observeOn(AndroidSchedulers.mainThread()) .doOnNext(progress -> { //下载进度回调,0-100,仅在进度有更新时才会回调,最多回调101次,最后一次回调文件存储路径 int currentProgress = progress.getProgress(); //当前进度 0-100 long currentSize = progress.getCurrentSize(); //当前已下载的字节大小 long totalSize = progress.getTotalSize(); //要下载的总字节大小 String filePath = progress.getResult(); //文件存储路径,最后一次回调才有内容 }) .filter(Progress::isCompleted)//下载完成,才继续往下走 .map(Progress::getResult) //到这,说明下载完成,返回下载目标路径 .as(RxLife.as(this)) //感知生命周期 .subscribe(s -> {//s为String类型,这里为文件存储路径 //下载完成,处理相关逻辑 }, throwable -> { //下载失败,处理相关逻辑 }); 复制代码
断点下载
相较于 下载
,仅仅是添加了 RANGE
头信息而已,其它没有任何差别
String destPath = getExternalCacheDir() + "/" + "Miaobo.apk"; long length = new File(destPath).length(); //已下载的文件长度 RxHttp.get("http://update.9158.com/miaolive/Miaolive.apk") //如果文件存在,则添加 RANGE 头信息 ,从上次断开的点,开始下载 .addHeader("RANGE", "bytes=" + length + "-", length > 0) .download(destPath) .as(RxLife.as(this)) //加入感知生命周期的观察者 .subscribe(s -> { //s为String类型 Log.e("LJX", "breakpointDownloadAndProgress=" + s); //下载成功,处理相关逻辑 }, throwable -> { //下载失败,处理相关逻辑 }); 复制代码
带进度断点下载
相较于 带进度下载
,仅仅是添加了 RANGE
头信息而已,其它没有任何差别
String destPath = getExternalCacheDir() + "/" + "Miaobo.apk"; long length = new File(destPath).length(); //已下载的文件长度 RxHttp.get("http://update.9158.com/miaolive/Miaolive.apk") //如果文件存在,则添加 RANGE 头信息 ,从上次断开的点,开始下载 .addHeader("RANGE", "bytes=" + length + "-", length > 0) .downloadProgress(destPath) .observeOn(AndroidSchedulers.mainThread()) //主线程回调 .doOnNext(progress -> { //下载进度回调,0-100,仅在进度有更新时才会回调 int currentProgress = progress.getProgress(); //当前进度 0-100 long currentSize = progress.getCurrentSize(); //当前已下载的字节大小 long totalSize = progress.getTotalSize(); //要下载的总字节大小 }) .filter(Progress::isCompleted)//过滤事件,下载完成,才继续往下走 .map(Progress::getResult) //到这,说明下载完成,拿到Http返回结果并继续往下走 .as(RxLife.as(this)) //加入感知生命周期的观察者 .subscribe(s -> { //s为String类型 //下载成功,处理相关逻辑 }, throwable -> { //下载失败,处理相关逻辑 }); 复制代码
注:
上面带进度断点下载中,返回的进度会从0开始,如果需要接着上次下载的进度,则可以在 downloadProgress
下再添加一个map操作符,添加上次已经下载好的长度,如下:
String destPath = getExternalCacheDir() + "/" + "Miaobo.apk"; long length = new File(destPath).length(); //已下载的文件长度 RxHttp.get("http://update.9158.com/miaolive/Miaolive.apk") //如果文件存在,则添加 RANGE 头信息 ,从上次断开的点,开始下载 .addHeader("RANGE", "bytes=" + length + "-", length > 0) .downloadProgress(destPath) .map(progress -> { if (length > 0) {//增加上次已经下载好的字节数,并更新进度 progress.addCurrentSize(length); progress.addTotalSize(length); progress.updateProgress(); } return progress; }) .observeOn(AndroidSchedulers.mainThread()) //主线程回调 .doOnNext(progress -> { //下载进度回调,0-100,仅在进度有更新时才会回调 int currentProgress = progress.getProgress(); //当前进度 0-100 long currentSize = progress.getCurrentSize(); //当前已下载的字节大小 long totalSize = progress.getTotalSize(); //要下载的总字节大小 }) .filter(Progress::isCompleted)//过滤事件,下载完成,才继续往下走 .map(Progress::getResult) //到这,说明下载完成,拿到Http返回结果并继续往下走 .as(RxLife.as(this)) //加入感知生命周期的观察者 .subscribe(s -> { //s为String类型 //下载成功,处理相关逻辑 }, throwable -> { //下载失败,处理相关逻辑 }); 复制代码
好了,文件上传、下载相关就介绍到这里了,到这你会发现,涉及到进度的监听,都使用了RxJava的 doOnNext
、 filter
、 map
这3个操作符,一切都那么的相似,极大的降低了学习成本。怎么样?是不是很优雅,欢迎打脸!!
最后,很大一部分功劳都要归功于RxJava的强大,感谢RxJava,向它致敬!!!!
下一文将继续使用RxJava强大的操作符,看看它与RxHttp又能擦出怎样的火花。 转载请注明出处,谢谢:pray: