使用RxJava2下载包含进程的文件

时间:2018-05-02 15:02:21

标签: rx-java rx-java2

正如标题所说,我想使用RxJava2和okhttp下载文件。并且还需要处理。

在我看来,数据流是String url - > Response - >乘以Float process

首先,我需要一个发出Single的{​​{1}}。

Response

接下来我需要Single.create((SingleOnSubscribe<Response>) emitter -> { emitter.onSuccess(xx);// or throw error }); 对吗?因为我想向Observer发出多个进程信息。

所以我在这里该怎么办?提前谢谢。

修改

我尝试将Flowable转换为Single

Flowable

但我不知道这样做是否合适。

修改

我不关心okhttp的详细信息,我只关心与Single.create((SingleOnSubscribe<Response>) emitter -> { emitter.onSuccess(xxx);// or throw error }).toFlowable() .flatMap((Function<Response, Publisher<Float>>) response -> Flowable.create(xxx)) .subscribe(process -> {}); } 相关的内容,例如RxJavaSingle

2 个答案:

答案 0 :(得分:0)

这是一个如何使用Retrofit 2,OkHttp,Okio和RxJava这样做的例子。

import com.squareup.okhttp.ResponseBody;
import okio.BufferedSink;
import okio.Okio;
import retrofit.Response;
import retrofit.http.GET;
import retrofit.http.Query;
import rx.Observable;

interface ApiService {
    @GET("/media/download")
    Observable<Response<ResponseBody>> download(@Query("id") String id);
}

public Observable<File> download(String id) {
    return service.download(id)
        .flatMap(this::saveFile);
}

public Observable<File> saveFile(Response<ResponseBody> response) {
    return Observable.create((Observable.OnSubscribe<File>) subscriber -> {
        try {
            // you can access headers of response
            String header = response.headers().get("Content-Disposition");
            // this is specific case, it's up to you how you want to save your file
            // if you are not downloading file from direct link, you might be 
            // lucky to obtain file name from header
            String fileName = header.replace("attachment; filename=", "");
            // will create file in global Music directory, can be any other 
            // directory, just don't forget to handle permissions

            File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC)
                    .getAbsoluteFile(), fileName);

            // No space before "(Environment.DIRECTORY_MUSIC)"
            BufferedSink sink = Okio.buffer(Okio.sink(file));
            // you can access body of response
            sink.writeAll(response.body().source());
            sink.close();
            subscriber.onNext(file);
            subscriber.onCompleted();
        } catch (IOException e) {
            e.printStackTrace();
            subscriber.onError(e);
        }
    });
}

答案 1 :(得分:0)

如果您使用改造,可以尝试此https://github.com/imfms/retrofit-rxjava-request-with-progress

如果不适应其中一个基础类:

首先使用okhttp async api。 第二次使用rx调度程序进行异步。