Okhttp上传文件的进度获取

下载进度的在之前的文章中实现过:
Android的Splash启动图的两种动态切换方式

根据服务器的数据声明上传文件的方法

    @Multipart
    @POST("upload")
    Observable uploadHeadPic(@Part MultipartBody.Part files);

借助okhttp的RequestBody我们构造一个FileRequestBody继承RequestBody

public class FileRequestBody extends RequestBody {
    private RequestBody mRequestBody;
    private LoadingListener mLoadingListener;
    private long mContentLength;

    public FileRequestBody(RequestBody requestBody, LoadingListener loadingListener) {
        mRequestBody = requestBody;
        mLoadingListener = loadingListener;
    }

    //文件的总长度
    @Override
    public long contentLength() {
        try {
            if (mContentLength == 0)
                mContentLength = mRequestBody.contentLength();
            return mContentLength;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return -1;
    }

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

    @Override
    public void writeTo(BufferedSink sink) throws IOException {
        ByteSink byteSink = new ByteSink(sink);
        BufferedSink mBufferedSink = Okio.buffer(byteSink);
        mRequestBody.writeTo(mBufferedSink);
        mBufferedSink.flush();
    }


    private final class ByteSink extends ForwardingSink {
        //已经上传的长度
        private long mByteLength = 0L;

        ByteSink(Sink delegate) {
            super(delegate);
        }

        @Override
        public void write(Buffer source, long byteCount) throws IOException {
            super.write(source, byteCount);
            mByteLength += byteCount;
            mLoadingListener.onProgress(mByteLength, contentLength());
        }
    }

    public interface LoadingListener {
        void onProgress(long currentLength, long contentLength);
    }
}

实现上传

RequestBody requestFile =
                RequestBody.create(MediaType.parse("multipart/form-data"), file);
        FileRequestBody fileRequestBody = new FileRequestBody(requestFile, new FileRequestBody.LoadingListener() {
            @Override
            public void onProgress(long currentLength, long contentLength) {
                //获取上传的比例
                Log.d("Tag---", currentLength + "/" + contentLength);
            }
        });
        //files是与服务器对应的key
        MultipartBody.Part body =
                MultipartBody.Part.createFormData("files", file.getName(), fileRequestBody);
        RetrofitHelper.userApi().uploadHeadPic(body).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1() {
                    @Override
                    public void call(UploadImgBean uploadImgBean) {
                        //上传成功
                    }
                }, new Action1() {
                    @Override
                    public void call(Throwable throwable) {
                       //上传失败
                    }
                });

你可能感兴趣的:(Okhttp上传文件的进度获取)