使用 OKHTTP3 上传带有进度条的多个文件
Upload multiple files with progress bar using OKHTTP3
public class CountingFileRequestBody extends RequestBody {
private static final int SEGMENT_SIZE = 2048; // okio.Segment.SIZE
private final File file;
private final ProgressListener listener;
private final String contentType;
public CountingFileRequestBody(File file, String contentType, ProgressListener listener) {
this.file = file;
this.contentType = contentType;
this.listener = listener;
}
@Override
public long contentLength() {
return file.length();
}
@Override
public MediaType contentType() {
return MediaType.parse(contentType);
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
Source source = null;
try {
source = Okio.source(file);
long total = 0;
long read;
while ((read = source.read(sink.buffer(), SEGMENT_SIZE)) != -1) {
total += read;
sink.flush();
this.listener.transferred(total);
}
} finally {
Util.closeQuietly(source);
}
}
public interface ProgressListener {
void transferred(long num);
}
}
我看到了上面获取文件上传进度的代码...并且代码是这样使用的
RequestBody requestBody = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addPart(
Headers.of("Content-Disposition", "form-data; name=\"image\"; filename=\"" + file.getName() + "\""),
new CountingFileRequestBody(file, "image/*", new CountingFileRequestBody.ProgressListener() {
@Override
public void transferred(long num) {
float progress = (num / (float) totalSize) * 100;
uploadData.progressValue = (int) progress;
handler.post(new Runnable() {
@Override
public void run() {
updateProgressBar(tempId);
}
});
}
})
)
.build();
Request request = new Request.Builder()
.tag(tempId)
.url(Constants.BASE_URL + apiPath)
.post(requestBody)
.build();
但该代码仅适用于单个文件上传,我对 JAVA 还是个新手,所以我不知道如何更改代码以适应我的多个文件上传...
下面是我的文件上传代码
MultipartBody.Builder multipartBody = new MultipartBody.Builder().setType(MultipartBody.FORM);
for (int g = 0; g < fileLists.size(); g++){
File file = fileLists.get(g);
multipartBody.addFormDataPart("files[]", file.getName(), RequestBody.create(MediaType.parse("*/*"), file));
}
multipartBody.addFormDataPart("lang", lang)
.addFormDataPart("user", myIDtoString)
.addFormDataPart("post", postText);
RequestBody requestBody = multipartBody.build();
Request request = new Request.Builder()
.url(Constants.submitPostUrl)
.post(requestBody)
.build();
请问我如何修改 Java Class 代码以适合我的上传代码
经过长时间的搜索,我终于让它工作了
这是我的class,不是针对单个文件请求,而是针对整个请求正文
public class CountingRequestBody extends RequestBody {
protected RequestBody delegate;
protected Listener listener;
protected CountingSink countingSink;
public CountingRequestBody(RequestBody delegate, Listener listener)
{
this.delegate = delegate;
this.listener = listener;
}
@Override
public MediaType contentType()
{
return delegate.contentType();
}
@Override
public long contentLength()
{
try
{
return delegate.contentLength();
} catch (IOException e)
{
e.printStackTrace();
}
return -1;
}
@Override
public void writeTo(BufferedSink sink) throws IOException
{
countingSink = new CountingSink(sink);
BufferedSink bufferedSink = Okio.buffer(countingSink);
delegate.writeTo(bufferedSink);
bufferedSink.flush();
}
protected final class CountingSink extends ForwardingSink
{
private long bytesWritten = 0;
public CountingSink(Sink delegate)
{
super(delegate);
}
@Override
public void write(Buffer source, long byteCount) throws IOException
{
super.write(source, byteCount);
bytesWritten += byteCount;
listener.onRequestProgress(bytesWritten, contentLength());
}
}
public static interface Listener
{
public void onRequestProgress(long bytesWritten, long contentLength);
}
}
多文件上传器
public void filesUploader(){
MultipartBody.Builder multipartBody = new MultipartBody.Builder().setType(MultipartBody.FORM);
for (int g = 0; g < itemLists.size(); g++){
File readFile = itemLists.get(g);
Uri uris = Uri.fromFile(readFile);
String fileExt = MimeTypeMap.getFileExtensionFromUrl(uris.toString());
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExt.toLowerCase());
multipartBody.addFormDataPart("files[]", readFile.getName(), RequestBody.create(MediaType.parse(mimeType), readFile));
}
multipartBody.addFormDataPart("someparams1", value1)
.addFormDataPart("someparams2", value2);
final CountingRequestBody.Listener progressListener = new CountingRequestBody.Listener() {
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onRequestProgress(long bytesRead, long contentLength) {
if (bytesRead >= contentLength) {
} else {
if (contentLength > 0) {
final int progress = (int)Math.round((((double) bytesRead / contentLength) * 100));
postProgressBar.setProgress(progress, true);
postProgressText.setText(progress+"%");
if(progress == 100){
}
}
}
}
};
OkHttpClient imageUploadClient = new OkHttpClient.Builder()
.addNetworkInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
if (originalRequest.body() == null) {
return chain.proceed(originalRequest);
}
Request progressRequest = originalRequest.newBuilder()
.method(originalRequest.method(),
new CountingRequestBody(originalRequest.body(), progressListener))
.build();
return chain.proceed(progressRequest);
}
})
.build();
RequestBody requestBody = multipartBody.build();
Request request = new Request.Builder()
.url(Constants.submitPostUrl)
.header("Accept", "application/json")
.header("Content-Type", "application/json")
.post(requestBody)
.build();
imageUploadClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
String mMessage = e.getMessage().toString();
//onError
Log.e("failure Response", mMessage);
}
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onResponse(Call call, Response response) throws IOException {
String mMessage = response.body().string();
//successful
}
});
}
public class CountingFileRequestBody extends RequestBody {
private static final int SEGMENT_SIZE = 2048; // okio.Segment.SIZE
private final File file;
private final ProgressListener listener;
private final String contentType;
public CountingFileRequestBody(File file, String contentType, ProgressListener listener) {
this.file = file;
this.contentType = contentType;
this.listener = listener;
}
@Override
public long contentLength() {
return file.length();
}
@Override
public MediaType contentType() {
return MediaType.parse(contentType);
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
Source source = null;
try {
source = Okio.source(file);
long total = 0;
long read;
while ((read = source.read(sink.buffer(), SEGMENT_SIZE)) != -1) {
total += read;
sink.flush();
this.listener.transferred(total);
}
} finally {
Util.closeQuietly(source);
}
}
public interface ProgressListener {
void transferred(long num);
}
}
我看到了上面获取文件上传进度的代码...并且代码是这样使用的
RequestBody requestBody = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addPart(
Headers.of("Content-Disposition", "form-data; name=\"image\"; filename=\"" + file.getName() + "\""),
new CountingFileRequestBody(file, "image/*", new CountingFileRequestBody.ProgressListener() {
@Override
public void transferred(long num) {
float progress = (num / (float) totalSize) * 100;
uploadData.progressValue = (int) progress;
handler.post(new Runnable() {
@Override
public void run() {
updateProgressBar(tempId);
}
});
}
})
)
.build();
Request request = new Request.Builder()
.tag(tempId)
.url(Constants.BASE_URL + apiPath)
.post(requestBody)
.build();
但该代码仅适用于单个文件上传,我对 JAVA 还是个新手,所以我不知道如何更改代码以适应我的多个文件上传...
下面是我的文件上传代码
MultipartBody.Builder multipartBody = new MultipartBody.Builder().setType(MultipartBody.FORM);
for (int g = 0; g < fileLists.size(); g++){
File file = fileLists.get(g);
multipartBody.addFormDataPart("files[]", file.getName(), RequestBody.create(MediaType.parse("*/*"), file));
}
multipartBody.addFormDataPart("lang", lang)
.addFormDataPart("user", myIDtoString)
.addFormDataPart("post", postText);
RequestBody requestBody = multipartBody.build();
Request request = new Request.Builder()
.url(Constants.submitPostUrl)
.post(requestBody)
.build();
请问我如何修改 Java Class 代码以适合我的上传代码
经过长时间的搜索,我终于让它工作了
这是我的class,不是针对单个文件请求,而是针对整个请求正文
public class CountingRequestBody extends RequestBody {
protected RequestBody delegate;
protected Listener listener;
protected CountingSink countingSink;
public CountingRequestBody(RequestBody delegate, Listener listener)
{
this.delegate = delegate;
this.listener = listener;
}
@Override
public MediaType contentType()
{
return delegate.contentType();
}
@Override
public long contentLength()
{
try
{
return delegate.contentLength();
} catch (IOException e)
{
e.printStackTrace();
}
return -1;
}
@Override
public void writeTo(BufferedSink sink) throws IOException
{
countingSink = new CountingSink(sink);
BufferedSink bufferedSink = Okio.buffer(countingSink);
delegate.writeTo(bufferedSink);
bufferedSink.flush();
}
protected final class CountingSink extends ForwardingSink
{
private long bytesWritten = 0;
public CountingSink(Sink delegate)
{
super(delegate);
}
@Override
public void write(Buffer source, long byteCount) throws IOException
{
super.write(source, byteCount);
bytesWritten += byteCount;
listener.onRequestProgress(bytesWritten, contentLength());
}
}
public static interface Listener
{
public void onRequestProgress(long bytesWritten, long contentLength);
}
}
多文件上传器
public void filesUploader(){
MultipartBody.Builder multipartBody = new MultipartBody.Builder().setType(MultipartBody.FORM);
for (int g = 0; g < itemLists.size(); g++){
File readFile = itemLists.get(g);
Uri uris = Uri.fromFile(readFile);
String fileExt = MimeTypeMap.getFileExtensionFromUrl(uris.toString());
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExt.toLowerCase());
multipartBody.addFormDataPart("files[]", readFile.getName(), RequestBody.create(MediaType.parse(mimeType), readFile));
}
multipartBody.addFormDataPart("someparams1", value1)
.addFormDataPart("someparams2", value2);
final CountingRequestBody.Listener progressListener = new CountingRequestBody.Listener() {
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onRequestProgress(long bytesRead, long contentLength) {
if (bytesRead >= contentLength) {
} else {
if (contentLength > 0) {
final int progress = (int)Math.round((((double) bytesRead / contentLength) * 100));
postProgressBar.setProgress(progress, true);
postProgressText.setText(progress+"%");
if(progress == 100){
}
}
}
}
};
OkHttpClient imageUploadClient = new OkHttpClient.Builder()
.addNetworkInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
if (originalRequest.body() == null) {
return chain.proceed(originalRequest);
}
Request progressRequest = originalRequest.newBuilder()
.method(originalRequest.method(),
new CountingRequestBody(originalRequest.body(), progressListener))
.build();
return chain.proceed(progressRequest);
}
})
.build();
RequestBody requestBody = multipartBody.build();
Request request = new Request.Builder()
.url(Constants.submitPostUrl)
.header("Accept", "application/json")
.header("Content-Type", "application/json")
.post(requestBody)
.build();
imageUploadClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
String mMessage = e.getMessage().toString();
//onError
Log.e("failure Response", mMessage);
}
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onResponse(Call call, Response response) throws IOException {
String mMessage = response.body().string();
//successful
}
});
}