web-dev-qa-db-ja.com

Android Retrofit-進捗通知を表示するためのonProgressUpdate

現在、Androidネットワーク通信にRetrofitによるレトロフィットを使用しています。タスクの進行中に進行状況を取得する方法はありますか。 ?

ユースケースは、圧縮またはスケーリングなしで完全な画像品質の画像をロードすることです。

私は非同期タスクでそれがどのように可能かを見ていますが、それはRetrofitを使用する目的を無効にするでしょう。しかし、それは私が取らなければならない道かもしれません。

37
John Shelley

この回答はレトロフィット1に対するものです。レトロフィット2と互換性のあるソリューションの場合 この回答を参照


私は同じ問題を抱えていて、やっとそれをやった。以前私はspring libを使用していましたが、以下に示すものはSpringで機能しましたが、InputStreamで使用するのを間違えたため一貫性がありませんでした。レトロフィットを使用するようにすべてのAPIを移動し、アップロードはリストの最後の1つでした。TypedFilewriteTo()をオーバーライドして、読み取ったバイト数を更新しますOutputStreamに。たぶんこれは改善できるかもしれませんが、私が言ったように、Springを使用していたときに作成したので、再利用しました。これはアップロード用のコードであり、アプリ上で機能しています。ダウンロードのフィードバックが必要な場合は、@ Streamingを使用してinputStreamを読み取ることができます。

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

CountingTypedFileは、TypedFileの単なるコピーですが、ProgressListenerを含みます。

68
Davi Alves

ProgressDialog、通知などに表示するために最大値を取得する場合.

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