gpt4 book ai didi

android - 使用 OKHTTP 跟踪分段文件上传的进度

转载 作者:IT老高 更新时间:2023-10-28 21:37:04 35 4
gpt4 key购买 nike

我正在尝试实现一个进度条来指示分段文件上传的进度。

我已阅读对此答案的评论 - https://stackoverflow.com/a/24285633/1022454我必须包装传递给 RequestBody 的接收器并提供一个回调来跟踪移动的字节。

我创建了一个自定义 RequestBody 并用 CustomSink 类包装了接收器,但是通过调试我可以看到字节正在由 RealBufferedSink 写入ln 44 并且自定义接收器写入方法只运行一次,不允许我跟踪移动的字节。

    private class CustomRequestBody extends RequestBody {

MediaType contentType;
byte[] content;

private CustomRequestBody(final MediaType contentType, final byte[] content) {
this.contentType = contentType;
this.content = content;
}

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

@Override
public long contentLength() {
return content.length;
}

@Override
public void writeTo(BufferedSink sink) throws IOException {
CustomSink customSink = new CustomSink(sink);
customSink.write(content);

}
}


private class CustomSink implements BufferedSink {

private static final String TAG = "CUSTOM_SINK";

BufferedSink bufferedSink;

private CustomSink(BufferedSink bufferedSink) {
this.bufferedSink = bufferedSink;
}

@Override
public void write(Buffer source, long byteCount) throws IOException {
Log.d(TAG, "source size: " + source.size() + " bytecount" + byteCount);
bufferedSink.write(source, byteCount);
}

@Override
public void flush() throws IOException {
bufferedSink.flush();
}

@Override
public Timeout timeout() {
return bufferedSink.timeout();
}

@Override
public void close() throws IOException {
bufferedSink.close();
}

@Override
public Buffer buffer() {
return bufferedSink.buffer();
}

@Override
public BufferedSink write(ByteString byteString) throws IOException {
return bufferedSink.write(byteString);
}

@Override
public BufferedSink write(byte[] source) throws IOException {
return bufferedSink.write(source);
}

@Override
public BufferedSink write(byte[] source, int offset, int byteCount) throws IOException {
return bufferedSink.write(source, offset, byteCount);
}

@Override
public long writeAll(Source source) throws IOException {
return bufferedSink.writeAll(source);
}

@Override
public BufferedSink writeUtf8(String string) throws IOException {
return bufferedSink.writeUtf8(string);
}

@Override
public BufferedSink writeString(String string, Charset charset) throws IOException {
return bufferedSink.writeString(string, charset);
}

@Override
public BufferedSink writeByte(int b) throws IOException {
return bufferedSink.writeByte(b);
}

@Override
public BufferedSink writeShort(int s) throws IOException {
return bufferedSink.writeShort(s);
}

@Override
public BufferedSink writeShortLe(int s) throws IOException {
return bufferedSink.writeShortLe(s);
}

@Override
public BufferedSink writeInt(int i) throws IOException {
return bufferedSink.writeInt(i);
}

@Override
public BufferedSink writeIntLe(int i) throws IOException {
return bufferedSink.writeIntLe(i);
}

@Override
public BufferedSink writeLong(long v) throws IOException {
return bufferedSink.writeLong(v);
}

@Override
public BufferedSink writeLongLe(long v) throws IOException {
return bufferedSink.writeLongLe(v);
}

@Override
public BufferedSink emitCompleteSegments() throws IOException {
return bufferedSink.emitCompleteSegments();
}

@Override
public OutputStream outputStream() {
return bufferedSink.outputStream();
}
}

有没有人举个例子说明我会怎么做?

最佳答案

您必须创建一个自定义 RequestBody 并覆盖 writeTo 方法,并且您必须将文件分段发送到接收器。在每个段之后刷新接收器是非常重要的,否则你的进度条将很快填满,而文件实际上并没有通过网络发送,因为内容将留在接收器中(它就像一个缓冲区)。

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);
}

}

您可以在我的 gist 中找到一个支持在 AdapterView 中显示进度并取消上传的完整实现:​​https://gist.github.com/eduardb/dd2dc530afd37108e1ac

关于android - 使用 OKHTTP 跟踪分段文件上传的进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25962595/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com