首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >RxJava2请求参数变化时如何更新已有订阅

RxJava2请求参数变化时如何更新已有订阅
EN

Stack Overflow用户
提问于 2018-10-07 06:55:30
回答 1查看 378关注 0票数 1

我有一个活动,每次用户输入发生变化时,我都会发出网络请求。

接口定义如下:

代码语言:javascript
运行
复制
interface Api {
  @GET("/accounts/check")
  fun checkUsername(@Query("username") username: String): Observable<UsernameResponse>
}

然后是管理所有内容的服务:

代码语言:javascript
运行
复制
class ApiService {

  var api: Api

  init {
    api = retrofit.create(Api::class.java)
  }

  companion object {
    val baseUrl: String = "https://someapihost"
    var rxAdapter: RxJava2CallAdapterFactory = RxJava2CallAdapterFactory.create()
    val retrofit: Retrofit = Retrofit.Builder()
            .baseUrl(baseUrl)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(rxAdapter)
            .build()


}

  fun checkUsername(username: String): Observable<UsernameResponse> {
    return api.checkUsername(username)
  }
}

然后,在我的活动中,每当EditText内容发生变化时,我都会发出这个调用:

代码语言:javascript
运行
复制
  private fun checkUsername(username: String) {
      cancelSubscription()
      checkUsernameDisposable = ApiService()
            .checkUsername(username)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
              updateUi(it)
      }
  }

因此,每次输入更改时,这都会创建一个新的一次性对象。这显然是不正确的。我想做的是用新网络调用的结果更新现有的订阅。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-07 07:14:11

首先,您的想法是正确的,为每个更改事件创建一个Observable的效率很低。

有两种方法可以解决这个问题:

One

您可以使用RxBinding来获取文本更改Observable,现在您可以将文本更改flatMap到您的apiService调用中,减少到一个disposable。

代码语言:javascript
运行
复制
disposable = RxTextView.textChanges(editText)
    .switchMap { ApiService().checkUsername(it) }
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe { updateUi(it) }

两个

您可以使用Subject作为EditText更改的通道,如下所示:

代码语言:javascript
运行
复制
val editTextChangesSubject: PublishSubject<String> = PublishSubject.create()

// when the editText changes call
editTextChangesSubject.onNext(newText)

disposable = editTextChangesSubject
        .switchMap { ApiService().checkUsername(it) }
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe { updateUi(it) }

现在也只剩下一个一次性的了!

注意:如果人们使用将视图逻辑与中间人逻辑分开的特定体系结构模式,则有时倾向于使用Subject技术,如果您不受此约束,则可以使用RxBinding

此外,值得一提的是,这两种方法将为您提供订阅每个文本更改事件时所没有的功能,比如使用debounceonBackpressureLatest等流控制操作符。

编辑

使用switchMap而不是flatMap,查看Here的区别

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52684030

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档