Retrofit2+okhttp3的上传body进度回调

UploadCallback.java
public interface UploadCallback {
    void onProgressUpdate(int percentage);
}
UploadFileRequestBody.java
public class UploadFileRequestBody extends RequestBody {
    private RequestBody mRequestBody;
    private BufferedSink bufferedSink;
    private UploadCallback listener;

    public UploadFileRequestBody(String jsonData, UploadCallback listener){
        mRequestBody = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), jsonData);
        this.listener = listener;
    }
    //ProgressRequestBody
    public UploadFileRequestBody(RequestBody requestBody, UploadCallback listener) {
        this.mRequestBody = requestBody;
        this.listener = listener;
    }
    @Override
    public MediaType contentType() {
        return mRequestBody.contentType();
    }

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

    @Override
    public void writeTo(BufferedSink sink) throws IOException {
        if (sink instanceof Buffer){
            //因为项目重写了日志拦截器,而日志拦截器里面调用了 RequestBody.writeTo方法,但是 它的sink类型是Buffer类型,所以直接写入
            //如果不这么做的话,上传进度最终会达到200%,因为被调用2次,而且日志拦截的writeTo是直接写入到 buffer 对象中,所以会很快;
            mRequestBody.writeTo(sink);
            return;
        }
        if (bufferedSink == null) {
            bufferedSink = Okio.buffer(sink(sink));
        }
        //写入
        mRequestBody.writeTo(bufferedSink);
        //必须调用flush,否则最后一部分数据可能不会被写入
        bufferedSink.flush();
    }

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

            @Override
            public void write(Buffer source, long byteCount) throws IOException {
                super.write(source, byteCount);
                if (contentLength == 0) {
                    //获得contentLength的值,后续不再调用
                    contentLength = contentLength();
                }
                //增加当前写入的字节数
                bytesWritten += byteCount;
                //回调
                if (listener != null){
                    //listener.uploadProgress(bytesWritten, contentLength);
                    listener.onProgressUpdate((int) (100 * bytesWritten / contentLength));
                }
            }
        };
    }
}

使用:

// 实现上传进度监听
var dialogLoading = DialogLoading(this)
//body为原本上传的RequestBody,在上传接口那里传入body1即可
var body1 = UploadFileRequestBody(body,object : UploadCallback {
                override fun onProgressUpdate(percentage: Int) {
                    runOnUiThread {

                         //percentage为进度值
                        dialogLoading.dialogLoadingshow(true,percentage) }

                }
            })


版权声明:本文为weixin_48001141原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。