Inn*_*ve1 1 android rx-java retrofit2 rx-java2
我有一个活动,每次用户输入更改时我都会向其发出网络请求.
api定义如下:
interface Api {
@GET("/accounts/check")
fun checkUsername(@Query("username") username: String): Observable<UsernameResponse>
}
Run Code Online (Sandbox Code Playgroud)
然后是管理它的服务:
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)
}
}
Run Code Online (Sandbox Code Playgroud)
然后在我的活动中,每当EditText内容发生变化时,我都会进行此调用:
private fun checkUsername(username: String) {
cancelSubscription()
checkUsernameDisposable = ApiService()
.checkUsername(username)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
updateUi(it)
}
}
Run Code Online (Sandbox Code Playgroud)
因此,每次输入变化时,这都会创建一个新的一次性用品.这显然是不正确的.我想要做的是使用新网络调用的结果更新现有订阅.
首先,你正在思考,Observable为每个变革事件创建一个远非有效.
有两种方法:
一
您可以使用RxBinding来更改文本Observable,现在您可以flatMap将文本更改为apiService调用,最多可以更改为一次性.
disposable = RxTextView.textChanges(editText)
.switchMap { ApiService().checkUsername(it) }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { updateUi(it) }
Run Code Online (Sandbox Code Playgroud)
二
您可以使用a Subject作为EditText此类更改的通道:
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) }
Run Code Online (Sandbox Code Playgroud)
现在这也是一次性的!
注意:人们有时倾向于使用这种Subject技术,如果他们使用的是将View逻辑与中间人逻辑分开的特定体系结构模式,如果你不受限制,那RxBinding就是要走的路.
此外,如果值得一提的是,这两种方法将为您提供订阅每个文本更改事件时不存在的权限,例如使用debounce或等流控制运算符onBackpressureLatest.
编辑:
用来switchMap代替flatMap,看看这里的差异