RxJava+Retrofit+OkHttp深入浅出-终极封装三(文件上传)

来源:互联网 发布:java 泛型 t ? 编辑:程序博客网 时间:2024/05/24 06:51

背景

在实际运用中上传是一个必不可少的功能,所以我们在封装二的基础上加入上传的功能,同时需要附带上传进度!

效果

这里写图片描述

实现

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);
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

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);                    }                });            }        };    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73

3自定义接口,回调progress进度

public interface UploadProgressListener {    /**     * 上传进度     * @param currentBytesCount     * @param totalBytesCount     */    void onProgress(long currentBytesCount, long totalBytesCount);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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);          }      }));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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());    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

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());        }    };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

终极封装专栏

RxJava+Retrofit+OkHttp深入浅出-终极封装专栏)


源码

传送门-源码地址


建议

如果你对这套封装有任何的问题和建议欢迎加入QQ群告诉我!

阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 宝宝功能性便秘怎么办 苹果x手机卡了怎么办 宝宝不吃水果蔬菜怎么办 小宝宝不拉粑粑怎么办 小宝宝个子不高怎么办 孩子不开口说话怎么办 孩子吹空调发烧怎么办 孩子上学不想上怎么办 孩子上学想留级怎么办 孩子口算太慢怎么办 孩子浮躁没耐心怎么办 如果孩子打妈妈怎么办 孩子英语成绩不好怎么办 小孩说话发音不准怎么办 小孩gk发音不准怎么办 大学无英语基础怎么办 孩子应用题理解不透怎么办 嫉妒一个人好痛苦怎么办 爱嫉妒别人怎么办心理 总有人嫉妒我怎么办 从小嫉妒闺蜜怎么办 怕闺蜜比我好怎么办 孩子不会做应用题怎么办 当你嫉妒别人怎么办 单位社保发票丢失怎么办 单位医保发票丢失怎么办 图书明细没有给怎么办 拼音拼不到一起怎么办 孩子不会拼拼音怎么办 小孩子不会拼拼音怎么办 小孩拼音发音不准怎么办 孩子声调不会标怎么办 孩子拼音发音不准怎么办 孩子学拼音不会怎么办? 孩子不会拼生字怎么办? 对数字不敏感怎么办 孩子说话不算数怎么办 儿童做事不认真怎么办 幼儿园小朋友爱打人怎么办 遇到熊孩子家长怎么办 小孩嘴烂了怎么办