wake-up-neo.com

Android Retrofit - onProgressUpdate zum Anzeigen der Statusmeldung

Ich verwende derzeit Retrofit by Square für Android Netzwerkkommunikation. Gibt es eine Möglichkeit, den Fortschritt während einer Aufgabe zu ermitteln, um eine Statusmeldung zu erstellen, ähnlich der, die Facebook beim Hochladen eines Bildes verwendet? ?

Ein Anwendungsfall wäre das Laden eines Bildes in voller Bildqualität ohne Komprimierung oder Skalierung.

Ich sehe, wie es mit einem Asynctask möglich ist, aber das würde den Zweck der Verwendung von Retrofit zunichte machen. Dies könnte jedoch der Weg sein, den ich nehmen müsste.

37
John Shelley

Diese Antwort gilt für Retrofit 1. Für eine mit Retrofit 2 kompatible Lösung siehe diese Antwort .


Ich hatte das gleiche Problem und habe es endlich geschafft. Ich habe früher spring lib verwendet und was ich hier zeige, hat für Spring funktioniert, war aber inkonsistent, da ich einen Fehler bei der Verwendung für den InputStream gemacht habe. Ich habe alle meine APIs verschoben, um Retrofit zu verwenden, und Upload war der letzte in der Liste. Ich habe nur TypedFile writeTo () überschrieben, um mich über die gelesenen Bytes zu aktualisieren zum OutputStream. Vielleicht kann dies verbessert werden, aber wie gesagt, ich habe es gemacht, als ich Spring verwendet habe, also habe ich es einfach wieder verwendet. Dies ist der Code zum Hochladen und er funktioniert für mich in meiner App. Wenn Sie Feedback zum Herunterladen wünschen, können Sie @Streaming verwenden und den inputStream lesen.

ProgressListener

public interface ProgressListener {
 void transferred(long num);
}

CountingTypedFile

public class CountingTypedFile extends TypedFile {

 private static final int BUFFER_SIZE = 4096;

 private final ProgressListener listener;

 public CountingTypedFile(String mimeType, File file, ProgressListener listener) {
    super(mimeType, file);
    this.listener = listener;
 }

 @Override public void writeTo(OutputStream out) throws IOException {
    byte[] buffer = new byte[BUFFER_SIZE];
    FileInputStream in = new FileInputStream(super.file());
    long total = 0;
    try {
        int read;
        while ((read = in.read(buffer)) != -1) {
            total += read;
            this.listener.transferred(total);
            out.write(buffer, 0, read);
        }
    } finally {
        in.close();
    }
 }
}

MyApiService

public interface MyApiService {
 @Multipart
 @POST("/files")
 ApiResult uploadFile(@Part("file") TypedFile resource, @Query("path") String path);
}

SendFileTask

private class SendFileTask extends AsyncTask<String, Integer, ApiResult> {
    private ProgressListener listener;
    private String filePath;
    private FileType fileType;

    public SendFileTask(String filePath, FileType fileType) {
        this.filePath = filePath;
        this.fileType = fileType;
    }

    @Override
    protected ApiResult doInBackground(String... params) {
        File file = new File(filePath);
        totalSize = file.length();
        Logger.d("Upload FileSize[%d]", totalSize);
        listener = new ProgressListener() {
            @Override
            public void transferred(long num) {
                publishProgress((int) ((num / (float) totalSize) * 100));
            }
        };
        String _fileType = FileType.VIDEO.equals(fileType) ? "video/mp4" : (FileType.IMAGE.equals(fileType) ? "image/jpeg" : "*/*");
        return MyRestAdapter.getService().uploadFile(new CountingTypedFile(_fileType, file, listener), "/Mobile Uploads");
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        Logger.d(String.format("progress[%d]", values[0]));
        //do something with values[0], its the percentage so you can easily do
        //progressBar.setProgress(values[0]);
    }
}

Das CountingTypedFile ist nur eine Kopie von TypedFile , enthält jedoch den ProgressListener.

68
Davi Alves

Wenn Sie den Maximalwert erhalten möchten, um ihn in einem ProgressDialog, einer Benachrichtigung usw. anzuzeigen.

ProgressListener

public interface ProgressListener {
    void transferred(long num, long max);
}

CountingTypedFile

public class CountingTypedFile extends TypedFile {

    private static final int BUFFER_SIZE = 4096;

    private final ProgressListener listener;

    public CountingTypedFile(String mimeType, File file, ProgressListener listener) {
        super(mimeType, file);
        this.listener = listener;
    }

    @Override
    public void writeTo(OutputStream out) throws IOException {
        byte[] buffer = new byte[BUFFER_SIZE];
        FileInputStream in = new FileInputStream(super.file());
        long total = 0;
        try {
            int read;
            while ((read = in.read(buffer)) != -1) {
                total += read;
                this.listener.transferred(total, super.file().length());
                out.write(buffer, 0, read);
            }
        } finally {
            in.close();
        }
    }
}
0
Gnzlt