RxJava+Retrofit+OkHttp实现文件上传
程序员文章站
2022-06-19 18:55:57
背景
在实际运用中上传是一个必不可少的功能,所以我们在封装二的基础上加入上传的功能,同时需要附带上传进度!
效果
实现
1.定义service接口
注意:mu...
背景
在实际运用中上传是一个必不可少的功能,所以我们在封装二的基础上加入上传的功能,同时需要附带上传进度!
效果
实现
1.定义service接口
注意:multipart是指定大文件上传过程中的标示,一般上传图片的过程中我们需要附带信息,所以我们需要用到@part指定传递的数值,multipartbody.part是指定传递的文件;
/*上传文件*/ @multipart @post("appyufaku/uploadheadimg") observable<baseresultentity<uploadresulte>> uploadimage(@part("uid") requestbody uid, @part("auth_key") requestbody auth_key,@part multipartbody.part file);
2.加入进度条
retrofit是基于okhttp的处理,所以我们可以自定义requestbody,复写writeto(bufferedsink sink)方法,得到传递的进度数据
public class progressrequestbody extends requestbody { //实际的待包装请求体 private final requestbody requestbody; //进度回调接口 private final uploadprogresslistener progresslistener; //包装完成的bufferedsink private bufferedsink bufferedsink; public progressrequestbody(requestbody requestbody, uploadprogresslistener progresslistener) { this.requestbody = requestbody; this.progresslistener = progresslistener; } /** * 重写调用实际的响应体的contenttype * @return mediatype */ @override public mediatype contenttype() { return requestbody.contenttype(); } /** * 重写调用实际的响应体的contentlength * @return contentlength * @throws ioexception 异常 */ @override public long contentlength() throws ioexception { return requestbody.contentlength(); } /** * 重写进行写入 * @param sink bufferedsink * @throws ioexception 异常 */ @override public void writeto(bufferedsink sink) throws ioexception { if (null == bufferedsink) { bufferedsink = okio.buffer(sink(sink)); } requestbody.writeto(bufferedsink); //必须调用flush,否则最后一部分数据可能不会被写入 bufferedsink.flush(); } /** * 写入,回调进度接口 * @param sink sink * @return sink */ private sink sink(sink sink) { return new forwardingsink(sink) { //当前写入字节数 long writtenbytescount = 0l; //总字节长度,避免多次调用contentlength()方法 long totalbytescount = 0l; @override public void write(buffer source, long bytecount) throws ioexception { super.write(source, bytecount); //增加当前写入的字节数 writtenbytescount += bytecount; //获得contentlength的值,后续不再调用 if (totalbytescount == 0) { totalbytescount = contentlength(); } observable.just(writtenbytescount).observeon(androidschedulers.mainthread()).subscribe(new action1<long>() { @override public void call(long along) { progresslistener.onprogress(writtenbytescount, totalbytescount); } }); } }; } }
3自定义接口,回调progress进度
public interface uploadprogresslistener { /** * 上传进度 * @param currentbytescount * @param totalbytescount */ void onprogress(long currentbytescount, long totalbytescount); }
4创建requestbody对象,加入进度
file file=new file("/storage/emulated/0/download/11.jpg"); requestbody requestbody=requestbody.create(mediatype.parse("image/jpeg"),file); multipartbody.part part= multipartbody.part.createformdata("file_name", file.getname(), new progressrequestbody(requestbody, new uploadprogresslistener() { @override public void onprogress(long currentbytescount, long totalbytescount) { tvmsg.settext("提示:上传中"); progressbar.setmax((int) totalbytescount); progressbar.setprogress((int) currentbytescount); } }));
5.传递附带信息
和封装二中post请求的方式一样,我们需要继承baseentity,复写里面的方法,然后设置需要传递的参数,因为是测试接口,所以我的参数直接写死在entity里面,part文件动态指定
/** * 上传请求api * created by wzg on 2016/10/20. */ public class uplaodapi extends baseentity { /*需要上传的文件*/ private multipartbody.part part; public uplaodapi(httponnextlistener listener, rxappcompatactivity rxappcompatactivity) { super(listener, rxappcompatactivity); setshowprogress(true); } public multipartbody.part getpart() { return part; } public void setpart(multipartbody.part part) { this.part = part; } @override public observable getobservable(httpservice methods) { requestbody uid= requestbody.create(mediatype.parse("text/plain"), "4811420"); requestbody key = requestbody.create(mediatype.parse("text/plain"), "21f8d9bcc50c6ac1ae1020ce12f5f5a7"); return methods.uploadimage(uid,key,getpart()); } }
6.post请求处理
请求和封装二中的请求一样,通过传递一个指定的httponnextlistener 对象来回调来监听结果信息,一一对应
private void uploadedo(){ file file=new file("/storage/emulated/0/download/11.jpg"); requestbody requestbody=requestbody.create(mediatype.parse("image/jpeg"),file); multipartbody.part part= multipartbody.part.createformdata("file_name", file.getname(), new progressrequestbody(requestbody, new uploadprogresslistener() { @override public void onprogress(long currentbytescount, long totalbytescount) { tvmsg.settext("提示:上传中"); progressbar.setmax((int) totalbytescount); progressbar.setprogress((int) currentbytescount); } })); uplaodapi uplaodapi = new uplaodapi(httponnextlistener,this); uplaodapi.setpart(part); httpmanager manager = httpmanager.getinstance(); manager.dohttpdeal(uplaodapi); } /** * 上传回调 */ httponnextlistener httponnextlistener=new httponnextlistener<uploadresulte>() { @override public void onnext(uploadresulte o) { tvmsg.settext("成功"); glide.with(mainactivity.this).load(o.getheadimgurl()).skipmemorycache(true).into(img); } @override public void onerror(throwable e) { super.onerror(e); tvmsg.settext("失败:"+e.tostring()); } };
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 男人就特别真诚
下一篇: 详解Linux文件锁flock