我遇到意外的kotlin和rxjava行爲。我用畢加索創造加載圖像的擴展功能擴展函數不會創建新的可觀察對象
fun Picasso.loadBitmap(url: String) : Observable<Bitmap>
= Observable.create<Bitmap> {
emitter ->
Log.d("picasso load bitmap", "me ${this}")
try {
val bitmap = load(url).centerCrop()
.resize(100, 100)
.transform(CircleTransformer())
.get()
emitter.onNext(bitmap)
emitter.onComplete()
} catch (e: IOException) {
emitter.onError(e)
}
}
林調用一個閉區間(幾乎在同一時間)這個多次這樣的,
picasso.loadBitmap(place.image_url)
.subscribeOn(Schedulers.io())
.retryWhen { error ->
error.zipWith(Observable.range(1, 5),
BiFunction<Throwable, Int, RetryWrapper> {
t1, t2 -> RetryWrapper(t2.toLong(), t1) })
.flatMap {
if(it.delay < 4){
Log.d(TAG, "retry no. ${it.delay} for ${place.image_url}")
Observable.timer(it.delay * 5, TimeUnit.SECONDS)
} else {
Log.d(TAG, "DMD ${place.image_url}")
Observable.error { it.error }
}
}
}
.subscribe (
{ bitmap ->
markers.find { it.place.id == place.id }?.let {
it.marker.icon = IconFactory.getInstance(context).fromBitmap(bitmap)
}
},
{
Log.e(TAG, "error decoding ${place.image_url}", it)
})
我希望每一次loadBitmap
會被調用,它會創建一個新的可觀察值。但我在日誌中得到這個
09-28 11:17:00.022 31694-32276/? D/picasso load bitmap: me [email protected]
09-28 11:17:00.068 31694-32277/? D/picasso load bitmap: me [email protected]
09-28 11:17:00.069 31694-31959/? D/picasso load bitmap: me [email protected]
09-28 11:17:00.108 31694-32278/? D/picasso load bitmap: me [email protected]
09-28 11:17:00.112 31694-32251/? D/picasso load bitmap: me [email protected]
09-28 11:17:00.125 31694-32260/? D/picasso load bitmap: me [email protected]
09-28 11:17:00.162 31694-31794/? D/picasso load bitmap: me [email protected]
09-28 11:17:00.192 31694-32280/? D/picasso load bitmap: me [email protected]
09-28 11:17:00.195 31694-32279/? D/picasso load bitmap: me [email protected]
09-28 11:17:00.219 31694-32281/? D/picasso load bitmap: me [email protected]
09-28 11:17:04.828 31694-32262/? D/picasso load bitmap: me [email protected]
09-28 11:17:14.885 31694-31793/? D/picasso load bitmap: me [email protected]
09-28 11:17:29.928 31694-32269/? D/picasso load bitmap: me [email protected]
可觀察的是所有loadBitmap
調用相同。 我需要他們有自己的觀察,因爲如果我不會,當retryWhen
失敗時,它不會繼續下一個失敗。我希望這是有道理的。
將defer
或flatmap
中的可觀察內容不會改變任何內容。
編輯我的代碼
override fun render(state: MainState) {
map?.let { map ->
val newMarkers: MutableList<PlaceMarker> = mutableListOf()
for(place in state.places) {
var placeMarker = placeMarkers.find { it.place.id == place.id }
if(placeMarker != null && map.markers.contains(placeMarker.marker)) {
newMarkers.add(placeMarker)
placeMarkers.remove(placeMarker)
} else {
if(placeMarker != null) placeMarkers.remove(placeMarker)
val option = MarkerOptions()
option.position = LatLng(place.latitude, place.longitude)
option.snippet = place.name
placeMarker = PlaceMarker(place, map.addMarker(option))
newMarkers.add(placeMarker)
picasso.loadBitmap(place.image_url)
.subscribeOn(Schedulers.io())
.retryWhen { error ->
error.zipWith(Observable.range(1, 5),
BiFunction<Throwable, Int, RetryWrapper> {
t1, t2 -> RetryWrapper(t2.toLong(), t1) })
.flatMap {
if(it.delay < 4){
Log.d(TAG, "retry no. ${it.delay} for ${place.image_url}")
Observable.timer(it.delay * 5, TimeUnit.SECONDS)
} else {
Log.d(TAG, "DMD ${place.image_url}")
Observable.error { it.error }
}
}
}
.subscribe (
{ bitmap ->
placeMarkers.find { it.place.id == place.id }?.let {
it.marker.icon = IconFactory.getInstance(context).fromBitmap(bitmap)
bitmap.recycle()
}
},
{
Log.e(TAG, "error decoding ${place.image_url}", it)
})
}
}
placeMarkers.forEach { it.marker.remove() }
placeMarkers.clear()
placeMarkers.addAll(newMarkers)
}
}
進出口使用的MVP,只是給你看廣一點。因此,在MODEL完成從服務器獲取數據之後,VIEW,render中的函數將被觸發。
謝謝,但爲什麼我只能得到1個週期的重試,沒有更多?我只能得到1個加載錯誤,但我有更多的網址加載。 – Hohenhiem
你可以添加一些關於這個問題的更多細節。 – guenhter
對不起, 我有從服務器獲取的地點列表。這個地方有img_urls,我需要在每個地方做一個標記,同時產生一個可觀察的圖像加載。 發生什麼事是,當我得到重試周期時,它不會繼續加載其餘的imgs。我希望這是有道理的。我張貼代碼。 – Hohenhiem