Suivi de l'évolution de plusieurs parties de téléchargement de fichiers à l'aide de OKHTTP
Je suis en train de mettre en œuvre une une barre de progression pour indiquer les progrès d'un multipart de téléchargement de fichiers.
J'ai lu à partir d'un commentaire sur cette réponse - https://stackoverflow.com/a/24285633/1022454 que j'ai pour envelopper l'évier passé à la RequestBody et de fournir un rappel qui suit les octets déplacé.
J'ai créé une coutume RequestBody et enveloppé de l'évier avec un CustomSink classe, cependant par le débogage et je peux voir que les octets sont écrits par RealBufferedSink ln 44 et la coutume évier de la méthode d'écriture est exécuté qu'une fois, ne m'autorise pas à suivre les octets déplacé.
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();
}
}
Quelqu'un a un exemple de comment je pourrais faire?
Vous devez vous connecter pour publier un commentaire.
Vous devez créer un personnalisé RequestBody et remplacer writeTo méthode, et de là, vous devrez envoyer vos fichiers dans l'évier, dans les segments. Il est très important que vous rincer l'évier après chaque segment, sinon votre barre de progression se remplit rapidement, sans que le fichier envoyé sur le réseau, parce que le contenu va rester dans l'évier (qui agit comme un tampon).
Vous pouvez trouver une mise en œuvre complète qui prend en charge l'affichage de progrès dans AdapterView et aussi l'annulation de téléchargements à mon gist: https://gist.github.com/eduardb/dd2dc530afd37108e1ac
BehaviorSubject
à émettre de la valeur de progression dansUploadsHandler
RequestBody
, pas besoin de mettre en œuvre personnaliséeBufferedSink
. Nous pouvons allouer Okio tampon à lire à partir du fichier image, et de connecter ce tampon à l'évier.Pour un exemple, voir ci-dessous
createCustomRequestBody
fonctionà utiliser -
Cette chose fonctionne très bien!
Gradle
Exemple complet de code ici
https://github.com/lizhangqu/CoreProgress