2016-04-23 24 views
5

üzerinde gözle görülebilir olan yeniden deneyin Ağ isteklerini senkronize olmayan şekilde ele almak için Android uygulamasında rxAndroid ve rxKotlin kullanıyorum. Artık, başarısız bir ağ isteğini yalnızca Snackbar düğmesine tıkladıktan sonra tekrar denemek istiyorum. ŞimdiRxAndroid -

Kodum:

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> 
} 

Api fabrikasında:

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() 
} 

Nasıl böyle bir şekilde gözlemlenebilir yeniden başlatabilirsiniz retrofit için

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() 
    } 

Şehirler arayüzü?

+0

Bir isteği tetikleyen nedir? Bunu senin kodundan göremiyorum. '' Şehirler() 'yi çağırmak yeni bir istek tetikliyor mu? –

+0

Yukarıda daha fazla kod ekledim. Evet, 'şehirler()' yeni bir isteği tetikler – Michael

+0

Ardından, tüm şehirlerService.cities() ... 'reaktif zincirini yeni bir yöntemle paketleyebilir ve bunu Snackbar'ın eylem dinleyicisinden arayabilirsin. –

cevap

1

Size zorlayıcı bir yol yerine gerçekten reaktif bir yol önerebilirim.

güncelleme konu sadece
.retryWhen(retryHandler -> 
      retryHandler.flatMap(nothing -> retrySubject.asObservable())) 
.subscribe() 

olduğunda:

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

Everything:

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

Ve snackbar üzerinde

bu yöntemi çağırın tıklayın

takın bu kod hemen sonra yöntemi) (abone RetryWhen yönteminin üzerinde kelimenin tam anlamıyla yinelenecek.

Bu yaklaşım hatası asla aboneye inmeyecek olsa da, retryHandler düz haritasına hata düzeltme ekleyebilirsin, ancak bu başka bir hikaye.

P.S. Üzgünüm, bu retrolambdas ile Java koduydu, ama bunu kolayca Kotlin'e dönüşeceksin.

+0

Ayrıca, https://android.jlelse.eu/rx-grokking-retrywhen-and-repeatwhen-on-android-development-examples-af5c3ed0872b adresinden alınan bu yaklaşımı denedim HOWEVER Android Studio, "Yöntem asObservable yöntemini çözemiyor" mesajını gösteriyor() ' –

+0

RxJava2'den kaldırılmış olan asObservable() yöntemi ile aynı hatayı aldım, ancak yeniden denemek için aynı işlevi görebileceğim başka bir yol var mı? – Neha