Android Retrofit - onProgressUpdate,用于显示进度通知

时间:2014-04-28 18:41:19

标签: android android-asynctask retrofit

我目前正在使用Square的Retrofit进行Android网络通信。有没有办法在创建进度通知的任务期间取得进展,类似于Facebook在上传图像时使用的进度通知?

使用案例可以在不压缩或缩放的情况下加载有望获得完整图像质量的图像。

我看到asynctask是如何实现的,但这会破坏使用Retrofit的目的。然而,这可能是我必须采取的路线。

2 个答案:

答案 0 :(得分:69)

此答案适用于Retrofit 1.适用于与Retrofit 2 see this answer兼容的解决方案。


我有同样的问题,最终设法做到了。我之前使用的是spring lib,我在下面展示的内容类似于Spring,但由于我在将它用于InputStream时出错,因此不一致。我移动了所有的API以使用改造,上传是列表中的最后一个,我只是覆盖 TypedFile writeTo()来更新我读取到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。

答案 1 :(得分:0)

如果你想得到最大值,以便在ProgressDialog,Notification等上显示它​​。

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