Skip to content

Instantly share code, notes, and snippets.

@wada811
Last active September 7, 2016 10:29
Show Gist options
  • Save wada811/0fa077602d1d2d9dc6e177876962365d to your computer and use it in GitHub Desktop.
Save wada811/0fa077602d1d2d9dc6e177876962365d to your computer and use it in GitHub Desktop.
Subject<T> vs Observable.OnSubscribe<T>

Subject<T> vs Observable.OnSubscribe<T>

interface OnItemClickListener {
    fun onItemClick(position: Int)
}

上記の Listener を Observable に変換したい時に以下の2つのクラスを用いた方法が考えられる。

  • Subject<T>
  • Observable.OnSubscribe<T>

どちらも問題なさそうだけど確証がない。 RxBinding は Observable.OnSubscribe<T> を用いた方法で実装されているのは何か理由があるのだろうか。 Subject<T> を用いた方法には問題があるのだろうか。

以下はそれぞれの方法での実装。

Subject<T> を用いた実装

private fun RecyclerView.itemClicks(): Observable<Int> {
    val subject = PublishSubject.create<Int>()
    val listener = RecyclerViewItemClickListener(this, object : OnItemClickListener {
        override fun onItemClick(position: Int) = subject.onNext(position)
    })
    return subject.doOnSubscribe { this.addOnItemTouchListener(listener) }.doOnUnsubscribe { this.removeOnItemTouchListener(listener) }
}

Observable.OnSubscribe<T> を用いた実装

private fun RecyclerView.itemClicks(): Observable<Int> = Observable.create(RecyclerViewItemClickOnSubscribe(this))

private class RecyclerViewItemClickOnSubscribe(private val recyclerView: RecyclerView) : Observable.OnSubscribe<Int> {
    override fun call(subscriber: Subscriber<in Int>) {
        val itemClickListener = RecyclerViewItemClickListener(recyclerView, object : OnItemClickListener {
            override fun onItemClick(position: Int) {
                if (!subscriber.isUnsubscribed) {
                    subscriber.onNext(position)
                }
            }
        })
        recyclerView.addOnItemTouchListener(itemClickListener)
        subscriber.add(object : MainThreadSubscription() {
            override fun onUnsubscribe() {
                recyclerView.removeOnItemTouchListener(itemClickListener)
            }
        })
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment