Okhttp上传文件的进度获取

作者: 倔强的炉包 | 来源:发表于2017-06-26 16:50 被阅读456次

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

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

        @Multipart
        @POST("upload")
        Observable<UploadImgBean> 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<UploadImgBean>() {
                        @Override
                        public void call(UploadImgBean uploadImgBean) {
                            //上传成功
                        }
                    }, new Action1<Throwable>() {
                        @Override
                        public void call(Throwable throwable) {
                           //上传失败
                        }
                    });
    

    相关文章

      网友评论

        本文标题:Okhttp上传文件的进度获取

        本文链接:https://www.haomeiwen.com/subject/xhjjcxtx.html