티스토리 뷰

728x90

검색 키워드: #Clicking back button twice to exit an activity with RxJava

먼저 Throttle, Debounce에 대해서 알아보겠습니다. 

/**
 * RxBinding의 Throttle 기능 사용하는 Button 함수
 * @param throttleSecond 해당 시간동안 중복 클릭 방지 (기본으로 1초)
 * @param subscribe 클릭 리스너 정의
 */
fun Button.onThrottleClick(throttleSecond: Long = 1, subscribe: (() -> Unit)? = null) = clicks()
        .throttleFirst(throttleSecond, TimeUnit.SECONDS)
        .observeOn(io.reactivex.rxjava3.android.schedulers.AndroidSchedulers.mainThread())
        .subscribe { subscribe?.invoke() }

위의 예제는 RxBinding 라이브러리를 이용해서, 다중 클릭을 방지하는 코드입니다. (실제 업무에서 사용하는 코드를 가져왔습니다.)

즉, Throttle은 특정 시간동안 하나의 이벤트만 동작하도록 하는 기술입니다. 

반면 Debounce는 특정 시간이 지난 후, 하나의 이벤트만 발생하도록 하는 기술입니다. 

둘의 차이점은 Throttle은 마지막 이벤트가 호출 된 후 일정 시간동안 이벤트 재호출을 막는 것이고, 
Debounce는 연이은 이벤트를 그룹화 하고, 마지막 호출만 실행한다는 것입니다. 

둘다 그룹화를 이용한다는 점에서는 비슷해보입니다.


Throttle은 너무 간단해서 이해가 되는데, Debounce는 좀 헷갈려서 다음과 같은 그림을 설명하겠습니다. 

위에 그림과 같이 그룹화가 끝나고 실제 이벤트가 실행되는 것을 확인할 수 있습니다. 


안드로이드에서는 Throttle, Debounce를 다음과 같이 이용할 수 있습니다. 

1. Throttle을 사용하여 로그인 버튼 중복 동작을 방지한다. 

2. Debounce를 사용하여 back버튼 2번 눌러 종료 기능을 구현한다. 


그럼, 이제 Android에서 실제로 사용하는 코드를 살펴볼까요? 

 

변수 파트

private val disposable = CompositeDisposable() // Disposable 관리 
private val backBtnSubject = PublishSubject.create<Boolean>() // backBtn 이벤트를 발생시킬 수 있는 Subject
private val BACK_BTN_EXIT_TIMEOUT = 2000 // 연속된 Back 버튼의 시간 간격 (2초안에 백버튼 2번 클릭시 앱 종료) 

 

함수 파트

override fun onResume() {
    super.onResume()

    disposable.add(backBtnSubject
        .debounce(100, TimeUnit.MILLISECONDS)
        .observeOn(AndroidSchedulers.mainThread())
        .doOnNext {
            Timber.v("backBtnSubject | onNext")
            Toast.makeText(this, "Please press back once more to exit", Toast.LENGTH_SHORT)
                .show()
        }
        .timeInterval(TimeUnit.MILLISECONDS)
        .skip(1)
        .filter { interval ->
            Timber.v("backBtnSubject | interval: $interval")
            interval.time() < BACK_BTN_EXIT_TIMEOUT
        }
        .subscribe {
            finishActivity(0)
            finish()

        })
}

override fun onPause() {
    super.onPause()
    disposable.clear()
}

override fun onBackPressed() {
    backBtnSubject.onNext(true)
}

 

 onResume() 안의 코드를 차근차근 설명하겠습니다. 

  1. debounce(100, TimeUnit.MILLESECONDS)
    • 0.1초 간격을 이벤트의 그룹으로 판단한다. (1000ms = 1초)
  2. observeOn(AndroidSchedulers.mainThread)
    • 설정 후의 시점, 즉 filter, map 등의 오퍼레이션에 대한 시점에 어떤 스레드를 사용할건지 정한다.
      (UI를 건드리는 작업의 경우엔 MainThread를 사용한다.)
  3. doOnNext
    • 실행할 코드를 작성한다.
  4. timeInterval(TimeUit.MILLESECONDS)
    • 타이머 작동 시작!
  5. skip(1)
    • 첫번째 이벤트는 건너띄고 실행하지 않는다.
      (첫번째 이벤트의 경우에만 다음 코드를 실행하지 않음)
  6. filter
    • filter 안의 코드가 true일 경우에만 다음
    • interval.time() < BACK_BTN_EXIT_TIMEOUT 이 true인 경우 == 2초안에 두번의 BACK 버튼 클릭이 있는 경우
  7. subscribe
    • 위의 filter를 통과하고 작성한 코드를 실행한다.
      (앱 종료)

 


도움이 되셨다면, 공감 또는 댓글을 달아주세요~ 큰 힘이 됩니다ㅎ


출처:
webclub.tistory.com/607
stackoverflow.com/questions/42715689/clicking-back-button-twice-to-exit-an-activity-with-rxjava

 

Clicking back button twice to exit an activity with rxjava

Looking for a subtle rx approach to exit an activity while pressing back button two times. boolean doubleBackToExitPressedOnce = false; @Override public void onBackPressed() { if (

stackoverflow.com

 

디바운스(Debounce)와 스로틀(Throttle ) 그리고 차이점

Throttle, Debounce & Difference 스로틀(Throttle) 과 디바운스(Debounce) 란 무엇일까? 이 두 가지 방법 모두 DOM 이벤트를 기반으로 실행하는 자바스크립트를 성능상의 이유로 JS의 양적인 측면, 즉 이벤트(ev.

webclub.tistory.com

 

'android' 카테고리의 다른 글

스레드간 데이터 통신  (0) 2021.02.16
android fullscreen transparent status bar  (1) 2021.01.22
clean Architecture 정리  (0) 2020.08.14
mvvm + aac 적용 샘플 코드  (0) 2020.05.18
버튼에 Ripple 효과 적용하기  (0) 2020.04.21
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함