RxJava+Retrofit+OkHttp实现文件上传
2017-11-17 10:06
639 查看
背景
在实际运用中上传是一个必不可少的功能,所以我们在封装二的基础上加入上传的功能,同时需要附带上传进度!
效果
实现
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()); } };
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
- JavaServlet的文件上传和下载实现方法
- java 网络编程之TCP通信和简单的文件上传功能实例
- Java实现文件上传服务器和客户端
- java实现多文件上传至本地服务器功能
- Java实现文件上传至服务器的方法
- java文件上传至ftp服务器的方法
- SpringBoot文件上传控制及Java 获取和判断文件头信息
- Java实现的文件上传下载工具类完整实例【上传文件自动命名】
- Retrofit+Rxjava实现文件上传和下载功能
- Java实现文件上传的两种方法(uploadify和Spring)
- java组件SmartUpload和FileUpload实现文件上传功能
- java 文件上传(单文件与多文件)
- Java 文件上传的实例详解
- 全面分析Java文件上传
相关文章推荐
- RxJava+Retrofit+OkHttp实现多文件下载之断点续传
- RxJava+Retrofit+OkHttp深入浅出-终极封装三(文件上传)
- Retrofit+RxJava实现app崩溃处理(一)上传文件
- RxJava + Retrofit+okhttp 封装,包含对相同格式请求数据、相同格式返回数据处理,显示 Material Design 加载 dialog,文件上传下载进度展示、全局异常捕捉。
- Retrofit+Rxjava实现文件上传和下载功能
- RxJava+Retrofit+OkHttp深入浅出-终极封装三(文件上传)
- RxJava+Retrofit+OkHttp深入浅出-终极封装三(文件上传)
- Retrofit2 & RxJava2实现单文件和多文件上传
- Rxjava+ReTrofit+okHttp深入浅出-终极封装三(文件上传)
- Retrofit+RxJava实现带进度下载文件
- RxJava+Retrofit+OkHttp深入浅出-终极封装四(多文件下载之断点续传)
- OkHttp与Retrofit上传文件详解
- RxJava2+Retrofit2+OkHttp3实现网络缓存
- Rxjava+Retrofit+okhttp+mvp实现
- OkHttp与Retrofit上传文件详解
- 【Android实战】----基于Retrofit实现多图片/文件、图文上传
- OkHttp学习(3)-->>同步、异步之上传文件至服务器(重写RequestBody方法,实现上传进度接口回调)
- 使用Retrofit+RxJava实现带进度下载文件
- Retrofit 2.0 超能实践(三),轻松实现文件/多图片上传/Json字符串
- 【Android实战】----基于Retrofit实现多图片/文件、图文上传