温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

RxJava+Retrofit+OkHttp如何实现文件上传

发布时间:2021-07-24 10:58:40 来源:亿速云 阅读:231 作者:小新 栏目:移动开发

这篇文章给大家分享的是有关RxJava+Retrofit+OkHttp如何实现文件上传的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

效果

RxJava+Retrofit+OkHttp如何实现文件上传

实现

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());     }   };

感谢各位的阅读!关于“RxJava+Retrofit+OkHttp如何实现文件上传”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI