【问题标题】:Chaining Calls on RxJava在 RxJava 上链接调用
【发布时间】:2020-05-23 09:15:26
【问题描述】:

在某些情况下,我需要链接 RxJava 调用。

最简单的一个:

视图模型:

fun onResetPassword(email: String) {
    ...
    val subscription = mTokenRepository.resetPassword(email)
        .observeOn(AndroidSchedulers.mainThread())
        .subscribeOn(Schedulers.io())
        .subscribe(
            //UI update calls
        )
    ...
}

我的仓库:

fun resetPassword(email: String): Single<ResetPassword> {
        return Single.create { emitter ->

            val subscription = mSomeApiInterface.resetPassword(email)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe({
                    emitter.onSuccess(...)
                }, { throwable ->
                    emitter.onError(throwable)
                })

            ...

        }
    }

我的问题

我需要添加吗:

.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())

为避免任何应用程序冻结的两个调用?还是 API 调用的第二个就足够了?

【问题讨论】:

  • 为什么你的存储库中有subscribe
  • @EpicPandaForce 起初我总是在 ViewModel 中完成我的逻辑。然后我意识到如果我们有多个存储库(数据库、远程、内存)如果我在 ViewModel 中执行逻辑并且这些存储库的数据模型不同,它可能会导致混乱。我不认为我的方法是对的。

标签: android kotlin rx-java2


【解决方案1】:

不,你不需要添加

.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())

用于存储库和视图模型。

.observeOn 通常应该在处理 ui 渲染之前调用。所以通常,在更新 ui 或发出 LiveData 值之前,您需要在 ViewModel 中使用它。

另外,你不需要在你的 repo 中订阅mSomeApiInterface,我认为最好还是直接返回,因为它是从你的方法链中获取的,像这样:

fun resetPassword(email: String): Single<ResetPassword> {
        return mSomeApiInterface.resetPassword(email);
    }

如果您需要任何映射,您可以正常链接它

fun resetPassword(email: String): Single<ResetPassword> {
        return mSomeApiInterface.resetPassword(email)
                .map{it -> }
    }

这样你可以编写你的 ViewModel 代码如下

fun onResetPassword(email: String) {
    ...
    // note the switcing between subscribeOn and observeOn
    // the switching is in short: subscribeOn affects the upstream,
    // while observeOn affects the downstream.
    // So we want to do the work on IO thread, then deliver results
    // back to the mainThread.
    val subscription = mTokenRepository.resetPassword(email)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(
            //UI update calls
        )
    ...
}

这将在 io 线程上运行 API 请求,将在 mainThread 上返回结果,这可能是您想要的。 :)

这个artical有一些关于subscribeOn和observeOn的很好的例子和解释,我强烈推荐查看。

【讨论】:

  • 你分享的文章很扎实而且很有趣。如果没有人想出更好的主意,我会接受这个答案。
【解决方案2】:
    Observable<RequestFriendModel> folderAllCall = service.getUserRequestslist(urls.toString());
        folderAllCall.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .map(result -> result.getRequested())
                .subscribe(this::handleResults, this::handleError);


   private void handleResults(List<Requested> folderList) {
        if (folderList != null && folderList.size() != 0) {

                            usersList.addAll(folderList);

            }
            adapter.notifyDataSetChanged();
        }
    }

    private void handleError(Throwable t) {
        Toast.makeText(getContext(),t.getMessage(),Toast.LENGTH_LONG).show();
    }

在界面中:

    @Headers({ "Content-Type: application/json;charset=UTF-8"})
@GET
Observable<RequestFriendModel> getUserRequestslist(@Url String url);

POJO 模型:

public class RequestFriendModel {

@SerializedName("requested")
@Expose
private List<Requested> requested = null;

public List<Requested> getRequested() {
    return requested;
}

public void setRequested(List<Requested> requested) {
    this.requested = requested;
}
}

【讨论】:

    猜你喜欢
    • 2017-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多