com.cmonbaby.http.stream.FileRequestBody Maven / Gradle / Ivy
Show all versions of http_lower Show documentation
package com.cmonbaby.http.stream;
import androidx.annotation.NonNull;
import com.cmonbaby.http.stream.listener.ProgressListener;
import java.io.File;
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;
/**
* Author: Simon
*
QO: 8950764
*
Email: [email protected]
*
WebSize: https://www.cmonbaby.com
*
Version: 1.0.0
*
Date: 2020/12/28
*
Description: 扩展OkHttp的请求体,实现上传时的进度提示
*/
public final class FileRequestBody extends RequestBody {
/**
* 实际请求体
*/
private final RequestBody requestBody;
/**
* 上传回调接口
*/
private final ProgressListener progressListener;
/**
* 包装完成的BufferedSink
*/
private BufferedSink bufferedSink;
public FileRequestBody(File file, ProgressListener progressListener) {
this.requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
this.progressListener = progressListener;
}
public FileRequestBody(RequestBody requestBody, ProgressListener progressListener) {
this.requestBody = requestBody;
this.progressListener = progressListener;
}
// 返回了本RequestBody的长度,也就是上传的totalLength
@Override
public long contentLength() throws IOException {
return requestBody.contentLength();
}
// 返回了requestBody的类型,想什么form-data/MP3/MP4/png等等等格式
@Override
public MediaType contentType() {
return requestBody.contentType();
}
@Override
public void writeTo(@NonNull BufferedSink sink) throws IOException {
if (bufferedSink == null) {
// 包装
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 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 (progressListener != null)
progressListener.onProgress(bytesWritten, contentLength, bytesWritten == contentLength);
}
};
}
}