2016-04-23 71 views
5

我在我的Android应用程序中使用rxAndroid和rxKotlin来异步处理网络请求。现在我只想点击Snackbar按钮后重试失败的网络请求。RxAndroid - 重试可观察点击

我现在代码:

interface CitiesService { 

    @GET("api/v1/cities") 
    fun cities(): Observable<List<String>> 

    @GET("api/v1/cities/{city}/coordinates") 
    fun coordinates(@Path("city") city: String): Observable<DoubleArray> 
} 

阿比厂:

object ApiFactory { 

    val citiesService: CitiesService 
     get() = retrofit.create(CitiesService::class.java) 

    private val retrofit: Retrofit 
     get() = Retrofit 
      .Builder() 
      .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 
      .addConverterFactory(GsonConverterFactory.create()) 
      .baseUrl(BASE_URL) 
      .build() 
} 

我如何能重新开始这样的方式可观察

于改造
val citiesService = ApiFactory.citiesService 

citiesService.cities() 
    .subscribeOn(Schedulers.newThread()) // fetch List<String> 
    .flatMap { Observable.from(it) }  // convert to sequence of String 
    .flatMap { city -> 
     citiesService.coordinates(city) // fetch DoubleArray 
      .map { City(city, it) }  // convert to City(String, DoubleArray) 
     } 
    .toList() 
    .observeOn(AndroidSchedulers.mainThread()) 
    .doOnNext { 
     listView.setOnItemClickListener { adapterView, view, position, id -> 
      onItemClick(it[position]) 
     } 
    } 
    .map { it.map { it.getName(activity) } } 
    .subscribe(
     { listAdapter = setupAdapter(it) }, 
     { showErrorSnackbar() } // handle error 
    ) 

fun showErrorSnackbar() { 
     Snackbar.make(listView, getString(R.string.not_available_msg), Snackbar.LENGTH_INDEFINITE) 
       .setAction(getString(R.string.snack_retry_btn), { 
        // retry observable 
       }) 
       .show() 
    } 

城市接口?

+0

什么是触发请求?我看不到你的代码。调用'cities()'是否会触发新的请求? –

+0

我在上面添加了更多的代码。是的,'cities()'触发一个新的请求 – Michael

+0

然后你可以将整个'citiesService.cities()...'反应链包装成一个新的方法并从Snackbar的动作监听器中调用它。 –

回答

1

我可以建议你真正的反应方式,而不是命令式的方式。

插入此代码后马上订阅()方法:

.retryWhen(retryHandler -> 
      retryHandler.flatMap(nothing -> retrySubject.asObservable())) 
.subscribe() 

其中更新对象就是:

@NonNull 
private final PublishSubject<Void> retrySubject = PublishSubject.create(); 

而且在小吃吧点击调用这个方法:

public void update() { 
    retrySubject.onNext(null); 
} 

一切高于retryWhen方法将重新执行。

尽管使用这种方法,错误永远不会下到用户,但您可以将错误条件添加到retryHandler平面映射中,但这是另一回事。

P.S.对不起,这是使用retrolambdas的Java代码,但您可以轻松将其转换为Kotlin。

+0

我也尝试了这种方法,取自https://android.jlelse.eu/rx-grokking-retrywhen-and-repeatwhen-on-android-development-examples-af5c3ed0872b然而,Android Studio显示消息'Can not resolve method asObservable ()' –

+0

得到了与从RxJava2中删除asObservable()方法相同的错误,但是有没有其他方式可以获得相同的重试功能 – Neha