从AsyncTask到RxJava的改进请求循环

时间:2017-10-16 14:23:01

标签: android android-asynctask retrofit rx-java

如何将以下代码从AsyncTask(从doInBackground方法)更改为RxJava?

MessageRq rq = new MessageRq();
rq.setId(id);
Call<MessageRs> response = App.getApi().getFirstCommand(rq);
nextLink = getNextUrl(response, rq);
for (int i = 0; i< 10; i++) {   
    response = App.getApi().authorize(nextLink, rq);
    nextLink = getNextUrl(response, rq);
}

getNextUrl方法如下所示:

private String getNextUrl(Call<MessageRs> response, MessageRq rq) throws Exception {
        Response<MessageRs> rs = response.execute();
        rq.setData(...);
        ...
        return rs.body().getLink();
}

我将Call<MessageRs>替换为Observable<MessageRs>,根据我的理解,我需要flatMap。但我不明白如何正确使用它......

myApi.getFirstCommand(rq)
       .subscribeOn(Schedulers.newThread())
       .flatMap(response -> { // How can I transfer here both response and rq?
           // and how to do it exactly 10 times?    
           // maybe after flatMap I should add .forEachWhile(cycle < 10) ?     
           String nextLink = getNextUrl(response, rq);
           myApi.authorize(nextLink, rq);
       })
       .observeOn(AndroidSchedulers.mainThread())
       .subscribe(// from what I understand, here I should update UI, right?);

1 个答案:

答案 0 :(得分:0)

您面临的一个问题是rq是一个可变对象,必须使用参数等进行更新。这些对象在RxJava中的功能方法并不能很好地发挥作用。话虽如此,它仍然可以使用可变状态,但你必须小心并行更新。

myApi.getFirstCommand(rq)
       .subscribeOn(Schedulers.newThread())
       .flatMap(response -> getNextUrlObservable(rq, response), 1 )
       .flatMap(response -> getNextUrlObservable(rq, response), 1 )
       .flatMap(response -> getNextUrlObservable(rq, response), 1 )
       .flatMap(response -> getNextUrlObservable(rq, response), 1 )
       .flatMap(response -> getNextUrlObservable(rq, response), 1 )
       .flatMap(response -> getNextUrlObservable(rq, response), 1 )
       .flatMap(response -> getNextUrlObservable(rq, response), 1 )
       .flatMap(response -> getNextUrlObservable(rq, response), 1 )
       .flatMap(response -> getNextUrlObservable(rq, response), 1 )
       .flatMap(response -> getNextUrlObservable(rq, response), 1 )
       .observeOn(AndroidSchedulers.mainThread())
       .subscribe(// from what I understand, here I should update UI, right?);

确保此序列不是并行执行所需的第一个更改是flatMap()的第二个参数,表示可用于评估输入的最大线程数。您也可以通过将take(1)应用于每个步骤来强制执行此操作。

您无法直接在可观察链中执行迭代。很可能建立一个观察链,即时构建链,或使用compose()运算符。