android - 如何在 Android 应用程序中执行对 REST API 的调用序列?
问题描述
我很难调用我的 api。我将 Reactivex 与 kotlin 和 Flowables 一起使用。如果我通过“If-Modified_since”标头传递的日期小于上次更新,我的 API 会返回一个项目列表。如果没有更新,我将作为应用返回 android 应用 304 错误。
我需要执行以下程序。1->我调用api 2->如果调用成功,将列表保存在Realm中并返回viewmodel 3->如果错误是304,我对item进行缓存搜索(Realm) 4 -> 如果是另一个错误,我会正常返回 ViewModel 的错误
这是下面的代码,但我不确定是不是这样。
override fun getTickets(eventId: String): Flowable<List<Ticket>> {
return factory
.retrieveRemoteDataStore()
.getTickets(eventId)
.map {
saveTickets(it)
it
}.onErrorResumeNext { t: Throwable ->
if (t is HttpException && t.response().code() == 304) {
factory.retrieveCacheDataStore().getTickets(eventId)
} else
//Should return error
}
问题是,最好的方法是什么?
谢谢你。
解决方案
我的大部分评论都是我的解释。
data class Ticket(val id:Int) {
companion object {
fun toListFrom(jsonObject: JSONObject): TICKETS {
/**do your parsing of data transformation here */
return emptyList()
}
}
}
typealias TICKETS = List<Ticket>
class ExampleViewModel(): ViewModel() {
private var error: BehaviorSubject<Throwable> = BehaviorSubject.create()
private var tickets: BehaviorSubject<TICKETS> = BehaviorSubject.create()
/**public interfaces that your activity or fragment talk to*/
fun error(): Observable<Throwable> = this.error
fun tickets(): Observable<TICKETS> = this.tickets
fun start() {
fetch("http://api.something.com/v1/tickets/")
.subscribeOn(Schedulers.io())
.onErrorResumeNext { t: Throwable ->
if (t.message == "304") {
get(3)
} else {
this.error.onNext(t)
/** this makes the chain completed gracefuly without executing flatMap or any other operations*/
Observable.empty()
}
}
.flatMap(this::insertToRealm)
.subscribe(this.tickets)
}
private fun insertToRealm(tickets: TICKETS) : Observable<TICKETS> {
/**any logic here is mainly to help you save into Realm**/
/** I think realm has the option to ignore items that are already in the db*/
return Observable.empty()
}
private fun get(id: Int): Observable<TICKETS> {
/**any logic here is mainly to help you fetch from your cache**/
return Observable.empty()
}
private fun fetch(apiRoute: String): Observable<TICKETS> {
/**
* boilerplate code
wether you're using Retrofit or Okhttp, that's the logic you
should try to have
* */
val status: Int = 0
val rawResponse = ""
val error: Throwable? = null
val jsonResponse = JSONObject(rawResponse)
return Observable.defer {
if (status == 200) {
Observable.just(Ticket.toListFrom(jsonResponse))
}
else if (status == 304) {
Observable.error<TICKETS>(Throwable("304"))
}
else {
Observable.error<TICKETS>(error)
}
}
}
override fun onCleared() {
super.onCleared()
this.error = BehaviorSubject.create()
this.tickets = BehaviorSubject.create()
}
}
推荐阅读
- rabbitmq - 在centos7中运行rabbitMq引发无法连接到节点rabbit@localhost:nodedown
- ironpython - Spotfire:使用ironpython的列的平均值,使用表达式
- javascript - 如何获得基于异步等待/承诺的响应
- c# - asp.net mvc 中某些客户端上的信号刷新问题
- node.js - 如何在节点 js 中将 gson 转换为 json?
- python - 返回“non_field_errors”:在邮递员中
- python - TensorFlow v2 替换 clip_gradients_by_norm
- jquery - 设置单选按钮 (jQuery)
- c# - 如何使用 RATE 函数在 C# 中计算有效产量?
- git-commit - git commit --squash 选项有什么作用,为什么有用?