android上传图片文件至c 服务器,Android 史上最优雅的实现文件上传、下载及进度的监听...

本文已授权「刘望舒」微信公众号独家原创发布

前言

本文将直接使用RxHttp库实现文件上传、下载、断点下载、进度的监听,不对RxHttp做过多讲解,如果对RxHttp不了解,请移步

本文目的在于让更多的读者知道RxHttp库,如果您已阅读上面4篇文章,本文可直接跳过,感谢你的支持。🙏🙏。

上传

RxHttp.postForm("http://...") //发送Form表单形式的Post请求

.add("key", "value")

.add("file1", new File("xxx/1.png")) //添加file对象

.add("file2", new File("xxx/2.png"))

.asString() //asXXX操作符,是异步操作

.as(RxLife.asOnMain(this)) //感知生命周期,并在主线程回调

.subscribe(s -> {

//上传成功,拿到Http返回值,这里返回值为String类型

}, throwable -> {

//上传失败

});

复制代码

注:如果需要对Http的返回值做解析,可在使用asParser操作符时,传入一个解析器Parser

带进度上传

带进度上传使用asUpload(Progress,Scheduler)操作符

RxHttp.postForm("http://www.......") //发送Form表单形式的Post请求

.add("key1", "value1")//添加参数,非必须

.add("file1", new File("xxx/1.png"))

.asUpload(progress -> {

//上传进度回调,0-100,仅在进度有更新时才会回调,最多回调101次,最后一次回调Http执行结果

int currentProgress = progress.getProgress(); //当前进度 0-100

long currentSize = progress.getCurrentSize(); //当前已上传的字节大小

long totalSize = progress.getTotalSize(); //要上传的总字节大小

}, AndroidSchedulers.mainThread())//指定主线程回调

.as(RxLife.as(this)) //感知生命周期

.subscribe(s -> { //s为String类型,由SimpleParser类里面的泛型决定的

//上传成功,处理相关逻辑

}, throwable -> {

//上传失败,处理相关逻辑

});

复制代码

注:如果需要对Http的返回值做解析,可使用asUpload(Parser,Progress,Scheduler)方法,传入一个解析器Parser

下载

//文件存储路径

String destPath = getExternalCacheDir() + "/" + System.currentTimeMillis() + ".apk";

RxHttp.get("http://update.9158.com/miaolive/Miaolive.apk")

.asDownload(destPath) //注意这里使用asDownload操作符,并传入本地路径

.as(RxLife.asOnMain(this)) //感知生命周期,并在主线程回调

.subscribe(s -> {

//下载成功,回调文件下载路径

}, throwable -> {

//下载失败

});

复制代码

带进度下载

带进度下载使用asDownload(String,Consumer,Scheduler)方法

//文件存储路径

String destPath = getExternalCacheDir() + "/" + System.currentTimeMillis() + ".apk";

RxHttp.get("http://update.9158.com/miaolive/Miaolive.apk")

.asDownload(destPath, progress -> {

//下载进度回调,0-100,仅在进度有更新时才会回调,最多回调101次,最后一次回调文件存储路径

int currentProgress = progress.getProgress(); //当前进度 0-100

long currentSize = progress.getCurrentSize(); //当前已下载的字节大小

long totalSize = progress.getTotalSize(); //要下载的总字节大小

}, AndroidSchedulers.mainThread()) //指定主线程回调

.as(RxLife.as(this)) //感知生命周期

.subscribe(s -> {//s为String类型,这里为文件存储路径

//下载完成,处理相关逻辑

}, throwable -> {

//下载失败,处理相关逻辑

});

复制代码

断点下载

断点下载相较于下载,仅需要调用setRangeHeader方法传入开始及结束位置即可(结束位置不传默认为文件末尾),其它没有任何差别

String destPath = getExternalCacheDir() + "/" + "Miaobo.apk";

long length = new File(destPath).length(); //已下载的文件长度

RxHttp.get("http://update.9158.com/miaolive/Miaolive.apk")

.setRangeHeader(length) //设置开始下载位置,结束位置默认为文件末尾

.asDownload(destPath)

.as(RxLife.asOnMain(this)) //加入感知生命周期的观察者

.subscribe(s -> { //s为String类型

Log.e("LJX", "breakpointDownloadAndProgress=" + s);

//下载成功,处理相关逻辑

}, throwable -> {

//下载失败,处理相关逻辑

});

复制代码

带进度断点下载

带进度断点下载相较于带进度下载仅需要调用setRangeHeader方法传入开始及结束位置即可(结束位置不传默认为文件末尾),其它没有任何差别

String destPath = getExternalCacheDir() + "/" + "Miaobo.apk";

long length = new File(destPath).length(); //已下载的文件长度

RxHttp.get("http://update.9158.com/miaolive/Miaolive.apk")

.setRangeHeader(length) //设置开始下载位置,结束位置默认为文件末尾

.asDownload(destPath, progress -> {

//下载进度回调,0-100,仅在进度有更新时才会回调

int currentProgress = progress.getProgress(); //当前进度 0-100

long currentSize = progress.getCurrentSize(); //当前已下载的字节大小

long totalSize = progress.getTotalSize(); //要下载的总字节大小

}, AndroidSchedulers.mainThread()) //指定主线程回调

.as(RxLife.as(this)) //加入感知生命周期的观察者

.subscribe(s -> { //s为String类型

//下载成功,处理相关逻辑

}, throwable -> {

//下载失败,处理相关逻辑

});

复制代码

注:上面带进度断点下载中,返回的进度会从0开始,如果需要衔接上次下载的进度,则调用asDownload(String,long,Consumer,Scheduler)方法传入上次已经下载好的长度(第二个参数),如下:

String destPath = getExternalCacheDir() + "/" + "Miaobo.apk";

long length = new File(destPath).length(); //已下载的文件长度

RxHttp.get("http://update.9158.com/miaolive/Miaolive.apk")

.setRangeHeader(length) //设置开始下载位置,结束位置默认为文件末尾

.asDownload(destPath, length, progress -> {

//下载进度回调,0-100,仅在进度有更新时才会回调

int currentProgress = progress.getProgress(); //当前进度 0-100

long currentSize = progress.getCurrentSize(); //当前已下载的字节大小

long totalSize = progress.getTotalSize(); //要下载的总字节大小

}, AndroidSchedulers.mainThread()) //指定主线程回调

.as(RxLife.as(this)) //加入感知生命周期的观察者

.subscribe(s -> { //s为String类型

//下载成功,处理相关逻辑

}, throwable -> {

//下载失败,处理相关逻辑

});

复制代码

多任务下载

多任务下载我们可以使用RxJava的merge操作符,如下:

List> downList = new ArrayList<>();

for (int i = 0; i < 3; i++) {

String destPath = getExternalCacheDir() + "/" + i + ".apk";

String url = "http://update.9158.com/miaolive/Miaolive.apk"

Observable down = RxHttp.get(url)

.asDownload(destPath);

downList.add(down);

}

//通过RxJava内部线程池,多任务并行下载

Observable.merge(downList)

.as(RxLife.as(this))

.subscribe(s -> {

//单个任务下载完成

}, throwable -> {

//下载出错

}, () -> {

//所有任务下载完成

});

复制代码

如果想监听每个任务的下载进度,也简单,用老方法即可,如下:

List> downList = new ArrayList<>();

for (int i = 0; i < 3; i++) {

String destPath = getExternalCacheDir() + "/" + i + ".apk";

String url = "http://update.9158.com/miaolive/Miaolive.apk"

Observable down = RxHttp.get(url)

.asDownload(destPath, progress -> {

//单个下载任务进度回调

}, AndroidSchedulers.mainThread())

downList.add(down);

}

//通过RxJava内部线程池,多任务并行下载

Observable.merge(downList)

.as(RxLife.as(this))

.subscribe(s -> {

//单个任务下载完成

}, throwable -> {

//下载出错

}, () -> {

//所有任务下载完成

});

复制代码

多任务上传

与多任务下载同理,不再讲述。

小结

好了,文件上传、下载相关就介绍到这里了,到这你会发现,不管是上传还是下载,进度的监听都极其的相似,极大的降低了学习成本。怎么样?是不是很优雅,欢迎打脸!!

最后,很大一部分功劳都要归功于RxJava的强大,感谢RxJava,向它致敬!!!!

下一文将继续使用RxJava强大的操作符,看看它与RxHttp又能擦出怎样的火花。

转载请注明出处,谢谢🙏

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值