如何停止观察旧的RxJava响应状态而不进行处理?

时间:2019-06-22 14:14:56

标签: android rx-java2 dispose

我有这种情况。用户通过单击按钮开始请求链。然后,他将上传两张照片。但是,在开始上传照片之后,他可能会返回并重新开始。

我的 CompositeDisposable()附加到viewMode l,它只会在onCleared()之后被清除。这就是为什么会发生奇怪的问题的原因:用户可能开始上传照片,返回,再次开始,并且来自旧请求的响应将被传递,将新照片上传之前!

我应该如何修改所有常规RxJava请求和zip运算符,使其仅在新请求而不是旧请求之后进行查找。

同样,我无法在每个按钮事件之前调用 CompositeDisposable.dispose(),因为那样会终止上传过程。

我只需要处置可能的旧答案。

这是我的样品:

//called two times, for uploading
fun uploadPhoto(){
compositeDisposable.add(
            apiService.networkRequest(linkedHashMap, url)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribeWith(object: DisposableSingleObserver<retrofit2.Response<String>>() {
                        override fun onSuccess(t: retrofit2.Response<String>) {
                            // will provide result even if two new uploadPhoto() methods gets called
                            handleResponse(t)
                        }

                        override fun onError(e: Throwable) {

                        }
                    }))

}
}

fun handleResponse(response: retrofit2.Response<String>)
{
    responseList.add(response) //saves number of responses
    if(responseList.size == 2)
    {
        //calls new network request and creates a new logic. 
    }
}

问题在于,在uploadPhoto()返回先前结果之后,handleResponse()被调用

1 个答案:

答案 0 :(得分:1)

好吧,如果我对您的情况有正确的理解,那么您想丢弃第一次上传的响应,并考虑第二次上传的响应,或者概括一下:忽略任何先前的响应,而仅考虑最新的响应。

如果是这样,那么一个简单的解决方案是在开始新的上传之前每次检查compositeDisposable。如果列表不为空,则丢弃所有内容并向其中添加新的一次性物品。

类似这样的东西:

fun uploadPhoto(){
   if(compositeDisposable.size() > 0){
       compositeDisposable.clear()
   }

   // ...
}

请注意使用compositeDisposable.clear()而不是.dispose()

关于您的后续问题:

因此,调用compositeDisposable.clear()将处理列表中的每个项目,更具体地说,这意味着工作线程将被中断,是的,在您的情况下,这意味着上传过程将被终止。

如果您希望继续上传,那么除了清除一次性物品外,您还必须提出其他机制。

我不确定您是否可以在Rx中执行此操作,但是不涉及Rx的一个主意是与每种上载关联某种uploadId,例如生成的随机哈希。该ID应该提供给您的网络层,然后在响应中传递回去。

然后在ViewModel中跟踪currentUploadId,并:

  • 每当用户执行新上传时,请使用新生成的ID更新currentUploadId
  • 无论何时收到handleResponse(...),您 如果没有,请与response.uploadId一起检查currentUploadId 匹配,那么您只需丢弃此响应。