首页 > 解决方案 > RxJava 取消对 'Single.fromCallable' 的请求,disposable.clear 导致 InterruptedIOException

问题描述

我在我的应用程序中使用 RxJava 和 AWS API Gateway。

代码在这里:

    @Override
    public Single<SearchResponse> searchPostsApiCall(String keyword, String offset) {
        return Single.fromCallable(() -> client.postSearch(keyword,offset));
    }

// to call api
getCompositeDisposable().add(searchPostsApiCall(keyword,offset)
                .subscribeOn(getSchedulerProvider().io())
                .observeOn(getSchedulerProvider().ui())
                .subscribe(response -> onResponseReceived(response, offset, finalType), this::onError)
        );

问题是,当用户在搜索过程中过于频繁地更改文本并且 api 调用已经在进行中时,我想在发送新命中之前取消先前的调用,因为我不希望由于查询更改而响应先前的命中。

我也尝试过使用disposable.cancel,但它给出了错误

'ApiClientException: java.io.InterruptedIOException: thread interrupted'

我怎样才能实现我的目标来保存我的命中?任何想法都将是可观的。

谢谢

标签: androidrx-javarx-java2

解决方案


某些 API 通过引发无法中继的异常来响应取消。如果此类崩溃是一致的,例如您总是InterruptedIOException从此类 API 中获得,您可以专门忽略此类异常,因此 RxJava 不会知道它们。

这有点难以实现,fromCallable因为您必须返回非空值,但您可能无法创建所涉及类型的实例。因此,我建议使用 create:

Single.create(emitter -> {
    try {
        emitter.onSuccess(client.postSearch(keyword,offset));
    } catch (InterruptedIOException ex) {
        // ignore
    } catch (Throwable ex) {
        emitter.onError(ex);
    }
});

编辑如果你可以创建 ąn SearchResponse,你可以留下fromCallable

Single.fromCallable(() -> {
    try {
        return client.postSearch(keyword,offset);
    } catch (InterruptedIOException ex) {
         // fromCallable won't actually emit this
        return new SearchResponse();
    }
});

推荐阅读