๊พธ์ค€ํ•จ์ด ์ง„๋ฆฌ๋‹ค!!

์–ด์ œ๋ณด๋‹ค ๋ฐœ์ „ํ•œ ์˜ค๋Š˜์ด ๋˜๊ณ ํ”ˆ ๐Ÿง‘๐Ÿปโ€๐Ÿ’ป ์˜ ๋ธ”๋กœ๊ทธ

Android/Kotlin

[Kotlin][Android] ์•ˆ๋“œ๋กœ์ด๋“œ RxBinding์— ๋Œ€ํ•ด์„œ(RxBinding์˜ ์‚ฌ์šฉ๋ฐฉ๋ฒ•)

๋ށ์š” 2022. 12. 21. 02:54

์•ˆ๋…•ํ•˜์„ธ์š” ๐Ÿ‘‹

์˜ค๋Š˜์€ ์ œ๊ฐ€ ํ”„๋กœ์ ํŠธ๋ฅผ ํ•˜๋ฉฐ ์‚ฌ์šฉํ–ˆ๋˜ RxBinding์— ๋Œ€ํ•ด์„œ 

ํฌ์ŠคํŒ…ํ•ด๋ณด๋ ค ํ•ฉ๋‹ˆ๋‹ค.

 

๋จผ์ €

RxBinding์ด๋ž€?

RxBinding์€ RxJava์™€ RxAndroid๋ฅผ ์ด์šฉํ•ด

์•ˆ๋“œ๋กœ์ด๋“œ์˜ ์œ„์ ฏ์ด๋‚˜ View์— Rx๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฝ๊ฒŒ ํ•ด์ฃผ๋Š” ์˜คํ”ˆ์†Œ์Šค์ž…๋‹ˆ๋‹ค. 

๋Œ€ํ‘œ์ ์œผ๋ก  TextWatcher์˜ ๊ธฐ๋Šฅ์ด๋‚˜ Button Click ์ด๋ฒคํŠธ ๋“ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค.


Rxbinding์„ ํ†ตํ•ด ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” Operator๋“ค๋กœ๋Š”

throttleFirst() , debounce()๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋‘ ํ•จ์ˆ˜์˜ ์ฐจ์ด์ ์— ๋Œ€ํ•ด ์šฐ์„  ์„ค๋ช… ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

 

throttleFirst()

์ •ํ•ด์ง„ ์‹œ๊ฐ„ ์•ˆ์— ์ผ์–ด๋‚˜๋Š” ์—ฌ๋Ÿฌ ์ด๋ฒคํŠธ๋“ค์€ ๊ฐ€์žฅ ๋จผ์ € ํ˜ธ์ถœ๋œ ์ด๋ฒคํŠธ๋งŒ ๋ฐฉ์ถœํ•˜๊ณ  ๊ทธ ์ดํ›„์— ๋“ค์–ด์˜จ ์ด๋ฒคํŠธ๋Š” ๋ฌด์‹œํ•˜๋Š” Operator์ž…๋‹ˆ๋‹ค.

ํ•ด๋‹น Operator๋ฅผ ํ†ตํ•ด ์ด์ค‘ ํด๋ฆญ์„ ๋ฐฉ์ง€ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๋งŽ์ด ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

์•„๋ž˜๋Š” throttleFirst()๋ฅผ ํ‘œํ˜„ํ•œ Marble Diagram์ž…๋‹ˆ๋‹ค.

throttleFirst() ๋‹ค์ด์–ด๊ทธ๋žจ

debounce()

์ด๋ฒคํŠธ๊ฐ€ ํ˜ธ์ถœ๋˜๊ณ  ์ •ํ•ด์ง„ ์‹œ๊ฐ„์ด ์ง€๋‚œ ํ›„์— ํ•ด๋‹น ์ด๋ฒคํŠธ๋ฅผ ๋ฐฉ์ถœํ•˜๋Š” Operator์ž…๋‹ˆ๋‹ค.

์•„๋ž˜ Marble Diagram์„ ๋ณด๋ฉฐ ์„ค๋ช…๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

 

debounce() ๋‹ค์ด์–ด๊ทธ๋žจ

์œ„ ๊ทธ๋ฆผ์„ ๋ณด์‹œ๋ฉด ๋นจ๊ฐ„ ์ด๋ฒคํŠธ๊ฐ€ ํ˜ธ์ถœ๋˜๊ณ  ์ •ํ•ด์ง„ ์‹œ๊ฐ„์ด ์ง€๋‚œ ํ›„์— ๋นจ๊ฐ„ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐฉ์ถœ๋˜๋ฉฐ

๋…ธ๋ž€์ƒ‰๊ณผ ๋…น์ƒ‰ ์ด๋ฒคํŠธ๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ์ง€๋งŒ, ๋งˆ์ง€๋ง‰์— ํ˜ธ์ถœ๋œ ๋…น์ƒ‰ ์ด๋ฒคํŠธ๊ฐ€ ํ˜ธ์ถœ๋œ ํ›„ ์ •ํ•ด์ง„ ์‹œ๊ฐ„์ด ์ง€๋‚œ ํ›„์—

๋…น์ƒ‰ ์ด๋ฒคํŠธ๋งŒ ๋ฐฉ์ถœ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์œ„์™€ ๊ฐ™์ด debounce()๋Š” ์—ฌ๋Ÿฌ ๋ฒˆ ์ด๋ฒคํŠธ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ๋„ ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰์— 

ํ˜ธ์ถœ๋œ ์ด๋ฒคํŠธ๊ฐ€ ์ •ํ•ด์ง„ ์‹œ๊ฐ„์ด ์ง€๋‚˜์•ผ ๋ฐฉ์ถœ์ด ๋˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ ‡๊ธฐ์— ํ•ด๋‹น Operator๋ฅผ ํ†ตํ•ด ์ด์ค‘ ํด๋ฆญ ๋ฐฉ์ง€ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์‹œ์—๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋ฒ„ํŠผ์„ ํด๋ฆญ ํ›„ ์ •ํ•ด์ง„ ์‹œ๊ฐ„์ด

์ง€๋‚˜์•ผ ๋งŒ ์ด๋ฒคํŠธ๊ฐ€ ๋ฒŒ์–ด์ง€๋Š” ์ด์ƒํ•œ? ์ƒํ™ฉ์ด ๋ฒŒ์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ˜…

๊ทธ๋ ‡๊ธฐ์— ํ•ด๋‹น Operator๋Š” EditText๋“ฑ๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์—ฌ ์ž…๋ ฅ๊ฐ’์— ๋Œ€ํ•œ ์œ ํšจ์„ฑ ์ฒดํฌ๋ฅผ ํ•  ๋•Œ ์ž์ฃผ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๐Ÿ˜Ž 


์•„์šธ๋Ÿฌ ์œ„ Operator์™€ ํ•จ๊ป˜ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ์œ„์ ฏ์˜ Operator๋“ค์„ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

clicks()

View์— ํด๋ฆญ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ Unit๊ฐ์ฒด๋ฅผ ๋ฐฉ์ถœํ•˜๋Š” Observable์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

์ฃผ๋กœ Button๊ณผ throttleFirst()์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

textChanges()

TextView ์ปดํฌ๋„ŒํŠธ์— ๋‹ด๊ธด text๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ๋ณ€๊ฒฝ๋˜๋Š” CharSequence๋ฅผ ๋ฐฉ์ถœํ•ด์ฃผ๋Š” operator์ž…๋‹ˆ๋‹ค.

EditText ๋˜ํ•œ TextView๋ฅผ ์ƒ์†๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ๋กœ EditText์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

์ด๋ ‡๊ฒŒ Operator๋“ค์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค.

์ด๋ฒˆ์—๋Š” Rxbinding์„ ์ฝ”๋“œ์— ์–ด๋–ป๊ฒŒ ์ ์šฉ์‹œํ‚ค๋Š”์ง€์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.


 

๋จผ์ € clicks()์˜ ์‚ฌ์šฉ๋ฐฉ๋ฒ•๊ณผ debounce()์™€ throttleFirst()๊ฐ€ ๊ฐ๊ฐ ์–ด๋–ป๊ฒŒ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€

์ฝ”๋“œ์™€ ์˜์ƒ์„ ํ†ตํ•ด ๋ณด์—ฌ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

์šฐ์„  gradle์— dependency๋ฅผ ์ถ”๊ฐ€ํ•ด์ค๋‹ˆ๋‹ค.

dependencies {
	...
    
    // RxBinding
    implementation "com.jakewharton.rxbinding3:rxbinding:3.1.0"
    
    ...
}
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

      <TextView
        android:id="@+id/debounceClickTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        android:text="Debounce"
        android:textSize="30sp"
        android:gravity="center"
        />

    <Button
        android:id="@+id/debounceButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/debounceClickTextView"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_margin="10dp"
        android:text="debounce"
        />

    <TextView
        android:id="@+id/clickTextViewDebounce"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/debounceButton"
        android:gravity="center"
        android:layout_margin="10dp"
        />

    <TextView
        android:id="@+id/throttleTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/clickTextViewDebounce"
        android:gravity="center"
        android:text="Throttle"
        android:textSize="30sp"
        />

    <Button
        android:id="@+id/throttleButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/throttleTextView"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_margin="10dp"
        android:text="throttle"
        />

    <TextView
        android:id="@+id/clickTextViewThrottle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/throttleButton"
        android:gravity="center"
        android:layout_margin="10dp"
        />

</androidx.constraintlayout.widget.ConstraintLayout>
class MainActivity : AppCompatActivity() {
    private lateinit var binding : ActivityMainBinding
    private lateinit var mCompositeDisposable: CompositeDisposable

    private var mDebounceButtonClicks = 0
    private var mThrottleButtonClicks = 0
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater).also {
            setContentView(it.root)
        }
        addListeners()
    }

    override fun onDestroy() {
        super.onDestroy()
        if(::mCompositeDisposable.isInitialized){
            mCompositeDisposable.clear()
        }
    }

    private fun addListeners() {
        with(binding){
            mCompositeDisposable = CompositeDisposable()

            val debounceButtonDisposable = debounceButton.clicks() // Debounce
                .debounce(1000 , TimeUnit.MILLISECONDS)
                .subscribe({ clickTextViewDebounce.text = (++mDebounceButtonClicks).toString() } , {it.printStackTrace()})

            val throttleButtonDisposable = throttleButton.clicks() // throttleFirst
                .throttleFirst(1000 , TimeUnit.MILLISECONDS)
                .subscribe({ clickTextViewThrottle.text = (++mThrottleButtonClicks).toString() } , {it.printStackTrace()})

            mCompositeDisposable.addAll(debounceButtonDisposable , throttleButtonDisposable)
        }
    }
}

์œ„์™€ ๊ฐ™์ด ์‹œ๊ฐ„์„ ์„ค์ •ํ•ด์ฃผ๊ณ  subscribe()์„ ํ†ตํ•ด ๋ฐœํ–‰๋œ event์—์„œ ํ•  ๋™์ž‘์„ ์ •์˜๋ฅผ ํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

subscribe์— ๋“ค์–ด๊ฐ€๋Š” 2๋ฒˆ์งธ ์ธ์ž๋Š” exception handler๋กœ

์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ์— ๋Œ€ํ•œ handler๋ฅผ ์ •์˜ํ•ด์ฃผ๋Š” ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค.

ํ•„์ž๋Š” exception ๋ฐœ์ƒ ์‹œ stackTrace๋ฅผ ์ฐ๋„๋ก ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

์•„์šธ๋Ÿฌ, ์œ„ ๋ณด์ด๋Š” CompositeDisposable์— ๋Œ€ํ•ด์„œ๋Š” ์•„๋ž˜์—์„œ ํ•œ ๋ฒˆ์— ์„ค๋ช…ํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์‹œ์—ฐ์˜์ƒ

์œ„ ์˜์ƒ์—์„œ ๋ณด์‹œ๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ด

debounce()์˜ ๊ฒฝ์šฐ์—๋Š” 7๋ฒˆ์„ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์Œ์—๋„ ๋งˆ์ง€๋ง‰ ๋™์ž‘๋งŒ ๋ฐœํ–‰์ด ๋˜์–ด +1๋งŒ ํ•œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๊ณ ,

throttleFirst()์˜ ๊ฒฝ์šฐ 7๋ฒˆ ํด๋ฆญ ์‹œ ์ฒซ ๋ฒˆ์งธ ์ด๋ฒคํŠธ์— ๋Œ€ํ•ด์„œ ๋ฐœํ–‰๋˜๊ณ  ๊ทธ ํ›„ 1์ดˆ์˜ ์‹œ๊ฐ„์ด ํ๋ฅธ ๋’ค์— ๋“ค์–ด์˜จ ์ด๋ฒคํŠธ์— ๋Œ€ํ•ด์„œ

ํ•œ๋ฒˆ ๋” ๋ฐœํ–‰ํ•˜์—ฌ +2๊ฐ€ ๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


์ด๋ฒˆ์—๋Š” textChanges()์˜ ์‚ฌ์šฉ๋ฐฉ๋ฒ•์„ ํ™•์ธํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/inputEditText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        android:padding="10dp"
        android:layout_margin="10dp"
        />

    <TextView
        android:id="@+id/verificationTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/inputEditText"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_margin="5dp"
        />
        
</androidx.constraintlayout.widget.ConstraintLayout>
class MainActivity : AppCompatActivity() {
    private lateinit var binding : ActivityMainBinding
    private lateinit var mCompositeDisposable: CompositeDisposable

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater).also {
            setContentView(it.root)
        }
        addListeners()
    }

    override fun onDestroy() {
        super.onDestroy()
        if(::mCompositeDisposable.isInitialized){
            mCompositeDisposable.clear()
        }
    }

    private fun addListeners() {
        with(binding){
            mCompositeDisposable = CompositeDisposable()
            val inputEditTextDisposable = inputEditText.textChanges()
                .debounce(1000 , TimeUnit.MILLISECONDS , AndroidSchedulers.mainThread())
                .subscribe({ verificationTextView.text = String.format("์ž…๋ ฅ๋œ ๊ธ€์ž๋Š” : %s์ž…๋‹ˆ๋‹ค." , it) } , {it.printStackTrace()})

            mCompositeDisposable.addAll(inputEditTextDisposable)
        }
    }

 

์‹œ์—ฐ์˜์ƒ

 

์œ„์—์„œ ์„ค๋ช…ํ–ˆ๋“ฏ debounce()๋Š” ๋งˆ์ง€๋ง‰ ์ด๋ฒคํŠธ๋งŒ ๋ฐœํ–‰ํ•˜์—ฌ ์‹คํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์œ„์ฒ˜๋Ÿผ EditText์—์„œ ์ž…๋ ฅ์„ ๋งˆ์น˜๊ณ  

1์ดˆ๊ฐ€ ์ง€๋‚œ ๋’ค์— TextView์— ๊ฐ’์„ ๋ณ€๊ฒฝ์‹œํ‚จ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๊ทธ๋ ‡๋‹ค๋ฉด ๋งˆ์ง€๋ง‰์œผ๋กœ Disposable์€ ๋ฌด์—‡์ผ๊นŒ์š”? ๐Ÿค”

์‚ฌ์ „์  ์˜๋ฏธ๋กœ Disposable์€ '1ํšŒ์„ฑ , ์ผํšŒ์šฉ์˜'๋ผ๋Š” ๋œป์œผ๋กœ

Observable ๊ฐ์ฒด๋ฅผ ๊ตฌ๋…ํ•˜๊ณ  ํ•ด๋‹น ๊ตฌ๋…์ด ๋” ์ด์ƒ ํ•„์š”ํ•˜์ง€ ์•Š์„ ๋•Œ๋Š” ๊ตฌ๋…์„ ํ•ด์ง€ํ•ด์•ผ ํ•˜๋Š”๋ฐ

์ด๊ฒƒ์„ ๋„์™€์ฃผ๋Š” ๊ฐ์ฒด๊ฐ€ disposable์ž…๋‹ˆ๋‹ค.

๋งŒ์ผ, ๊ตฌ๋…์„ ํ•ด์ง€ํ•˜์ง€ ์•Š๊ณ  ๊ณ„์† stream์„ ๋‚จ๊ฒจ ๋‘๊ฒŒ ๋œ๋‹ค๋ฉด

memory leak์ด ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์œผ๋ฏ€๋กœ ๋” ์ด์ƒ ํ•ด๋‹น ๊ตฌ๋…์— ๋Œ€ํ•ด ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค๋ฉด

์ ์ ˆํ•˜๊ฒŒ ๊ตฌ๋…์„ ํ•ด์ง€ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

๊ตฌ๋…์„ ํ•ด์ง€ํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” 2๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.


1. dispose() ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์ง์ ‘ disposable๊ฐ์ฒด๋ฅผ ์ œ๊ฑฐํ•œ๋‹ค.

 

2. CopositeDisposable๊ฐ์ฒด๋ฅผ ํ™œ์šฉํ•˜์—ฌ ํ•œ๋ฒˆ์— ์ œ๊ฑฐํ•œ๋‹ค.


class MainActivity : AppCompatActivity() {
    private lateinit var binding : ActivityMainBinding
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater).also {
            setContentView(it.root)
        }
        val disposable = binding.button.clicks().subscribe{
        	// something to do 
        }
        disposable.dispose() // 1๋ฒˆ ๋ฐฉ๋ฒ•
        
    }
}

 

class MainActivity : AppCompatActivity() {
    private lateinit var binding : ActivityMainBinding
    private lateinit var mCompositeDisposable: CompositeDisposable

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater).also {
            setContentView(it.root)
        }
        val disposable = binding.button.clicks().subscribe{
        	// something to do 
        }
        mCompositeDisposable = CompositeDisposable(disposable)
    }

    override fun onDestroy() {
        super.onDestroy()
        if(::mCompositeDisposable.isInitialized){
            mCompositeDisposable.clear() // 2๋ฒˆ ๋ฐฉ๋ฒ•
        }
    }

 

๊ฐ๊ฐ์˜ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์€ ์œ„ ์ฝ”๋“œ๋ฅผ ์ฐธ๊ณ  ๋ฐ”๋ž๋‹ˆ๋‹ค.

CompsiteDisposable ๊ฐ™์€ ๊ฒฝ์šฐ์—๋Š” ๋ชจ๋“  Disposable์„ ํ•œ ๋ฒˆ์— ๊ด€๋ฆฌ๊ฐ€ 

๊ฐ€๋Šฅํ•˜๊ธฐ์— ์—ฌ๋Ÿฌ ๊ฐ€์ง€ disposable๊ฐ์ฒด๋ฅผ ํ•ด์ง€ํ•  ๋•Œ๋Š” ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ํ†ตํ•œ ๋ฐฉ๋ฒ•์ด ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๐Ÿค”

 

์ด์ƒ์œผ๋กœ RxBinding์— ๋Œ€ํ•œ ํฌ์ŠคํŒ…์„ ๋งˆ์น˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์˜ค๋Š˜๋„ ์ฆ์ฝ” ํ•˜์„ธ์š” :)