retrofit显示上传文件进度

  首先说一下,如果是使用了Interceptor来拦截请求log的话,会导致上传两遍,而导致上传失败,会抱一个protcolException,unexpected of Stream,那么你要是上传的话就注释掉日志就可以了。

  其实这个东西的重点是写一个集成RequestBody的类就可以了,网上一大堆大同小异:

import java.io.IOException;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import okio.Buffer;
import okio.BufferedSink;
import okio.ForwardingSink;
import okio.Okio;
import okio.Sink;

/**
 * Created by Administrator on 2017/5/24 0024.
 */

public class CountingRequestBody extends RequestBody {
    protected RequestBody requestBody;
    private UploadListener listener;
//    private CountingSink countingSink;
    private BufferedSink bufferedSink;

    public CountingRequestBody(RequestBody requestBody, UploadListener listener) {
        this.requestBody = requestBody;
        this.listener = listener;
    }

    @Override
    public MediaType contentType() {
        return requestBody.contentType();
    }

    @Override
    public long contentLength() throws IOException {
        return requestBody.contentLength();
    }

//    @Override
//    public void writeTo(BufferedSink sink) throws IOException {
//        countingSink = new CountingSink(sink);
//        if (bufferedSink == null)
//            bufferedSink = Okio.buffer(countingSink);
//        requestBody.writeTo(bufferedSink);
//        bufferedSink.flush();
//    }

    @Override
    public void writeTo(BufferedSink sink) throws IOException {
//        countingSink = new CountingSink(sink);
        if (bufferedSink == null)
            bufferedSink = Okio.buffer(sink(sink));
        //写入
        requestBody.writeTo(bufferedSink);
        //必须调bubufferedSink.flush();不然最后一部分数据可能不会被写入
        bufferedSink.flush();
    }

    private Sink sink(Sink sink) {
        return new ForwardingSink(sink) {
            long byteWritten = 0L;//当前写入字节数
            long contentLength = 0L;//总字节长度,避免多次调用contentLength()方法

            @Override
            public void write(Buffer source, long byteCount) throws IOException {
                super.write(source, byteCount);
                if (contentLength == 0)
                    contentLength = contentLength();//获取总字节长度,避免多次调用
                byteWritten += byteCount;//累计当前写入字节数
                if (listener != null)
                    listener.onRequestProgress(byteWritten, contentLength,byteWritten == contentLength);
            }
        };
    }

//    protected final class CountingSink extends ForwardingSink {
//        long byteWriten = 0L;
//        Long contentLength = 0L;
//
//        public CountingSink(Sink delegate) {
//            super(delegate);
//        }
//
//        @Override
//        public void write(Buffer source, long byteCount) throws IOException {
//            super.write(source, byteCount);
//            byteWriten += byteCount;
//            if (contentLength == 0)
//                contentLength = contentLength();
//            listener.onRequestProgress(byteWriten, contentLength);
//        }
//    }

    public interface UploadListener {
        void onRequestProgress(long byteWrited, long contentLength,boolean done);
    }

我上面的类里面有注释,,其实是一样的代码,,,我懒得删掉。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值