扩展函数不会创建新的Observable对象

我有kotlin和rxjava意想不到的行为。 我使用picasso创建了一个用于加载图像的扩展function

fun Picasso.loadBitmap(url: String) : Observable = Observable.create { 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 { t1, t2 -> RetryWrapper(t2.toLong(), t1) }) .flatMap { if(it.delay  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被调用时,都会创建一个新的observable。 但我在日志中得到了这个

 09-28 11:17:00.022 31694-32276/? D/picasso load bitmap: me com.squareup.picasso.Picasso@c894e26 09-28 11:17:00.068 31694-32277/? D/picasso load bitmap: me com.squareup.picasso.Picasso@c894e26 09-28 11:17:00.069 31694-31959/? D/picasso load bitmap: me com.squareup.picasso.Picasso@c894e26 09-28 11:17:00.108 31694-32278/? D/picasso load bitmap: me com.squareup.picasso.Picasso@c894e26 09-28 11:17:00.112 31694-32251/? D/picasso load bitmap: me com.squareup.picasso.Picasso@c894e26 09-28 11:17:00.125 31694-32260/? D/picasso load bitmap: me com.squareup.picasso.Picasso@c894e26 09-28 11:17:00.162 31694-31794/? D/picasso load bitmap: me com.squareup.picasso.Picasso@c894e26 09-28 11:17:00.192 31694-32280/? D/picasso load bitmap: me com.squareup.picasso.Picasso@c894e26 09-28 11:17:00.195 31694-32279/? D/picasso load bitmap: me com.squareup.picasso.Picasso@c894e26 09-28 11:17:00.219 31694-32281/? D/picasso load bitmap: me com.squareup.picasso.Picasso@c894e26 09-28 11:17:04.828 31694-32262/? D/picasso load bitmap: me com.squareup.picasso.Picasso@c894e26 09-28 11:17:14.885 31694-31793/? D/picasso load bitmap: me com.squareup.picasso.Picasso@c894e26 09-28 11:17:29.928 31694-32269/? D/picasso load bitmap: me com.squareup.picasso.Picasso@c894e26 

所有的loadBitmap调用的observable都是一样的。 我需要他们有自己的观察,因为如果我不会,当重retryWhen失败时,它不会继续下一个失败。 我希望这是有道理的。

把可观察的内部deferflatmap不会改变任何东西。

编辑我的代码

 override fun render(state: MainState) { map?.let { map -> val newMarkers: MutableList = 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 { t1, t2 -> RetryWrapper(t2.toLong(), t1) }) .flatMap { if(it.delay  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中的函数将被触发。

你必须在这里小心。 这个关键字在

 Log.d("picasso load bitmap", "me ${this}") 

不针对Observable而是接收者types。 在你的情况下, Picasso 。 你在me com.squareup.picasso.Picasso@c894e26的日志里看到me com.squareup.picasso.Picasso@c894e26

好消息是,每次调用loadBitmap ,都会得到一个Observable的新实例。 你可以检查这个:

 val observable = picasso.loadBitmap(place.image_url) Log.d("observable for picasso", "$observable") observable.subscribeOn(Schedulers.io())... 

所以你看,你总是在同一个picasso实例上调用loadBitmap ,这就是为什么你会得到相同的输出。 但是,每个单独的调用loadBitmap都会创建一个新的Observable

所以你的代码很好。