RxJava로 뒤로가기 버튼 확인 기능 구현하기

뱅크샐러드 앱이 나날이 성장해 나가면서, 유저분들의 피드백을 많이 들을 수 있게 되었습니다.

iOS는 앱스토어 전체 무료 차트 3위까지 올라갔었습니다. Do you know Banksalad?

안드로이드 앱 같은 경우에는 뒤로가기 버튼을 눌렀을 때 바로 앱이 종료되는게 너무 불편하다는 피드백이 많이 들어와 해당 기능을 추가하기로 결정했습니다.

네이버 웹툰 앱의 예시

이 기능을 구현한 많은 블로그 글들을 보면 대부분 Handler.postDelayed 를 활용하거나, 변수를 따로 만들어서 뒤로가기 버튼을 눌렀을 때 누른 시간을 캐싱하는 방식으로 작업한 케이스가 많은데, 이 글에서는 저희가 RxJava를 활용해서 구현한 방법에 대해 소개해드리고자 합니다.

Subject를 만들고,

먼저 뒤로가기 버튼을 눌렀을 때 이벤트를 emitSubject를 만들어줍니다. SubjectObservable이면서 동시에 Subscriber의 역할을 하기 때문에 UI Event 뿐만 아니라 다양한 종류의 Item을 발행하고 처리할 때 Subject를 활용하면 쉽게 해결할 수 있습니다.

onComplete이 호출되기 직전의 Item만 받는 AsyncSubject, 가장 최근 emitItem으로 구독을 시작하는 BehaviorSubject, 구독 시점부터 발행된 모든 Item을 받는 PublishSubject, 구독 이전의 모든 Item들을 받는ReplaySubject 이렇게 총 4가지 Subject가 있는데요, 이 기능 같은 경우는 취소키를 눌렀을 때 발생하는 이벤트들의 시간 간격을 판별하는 로직이 필요하기 때문에 기본값을 가지는 BehaviorSubject를 생성해주었습니다.

Subject에 데이터를 emit하는 방법은 매우 간단합니다. subject.onNext() 를 해주면 끝! 여기서 주의할 점은 SubjectSerializedSubject 로 만들지 않으면 thread safe하지 않기 때문에 여러 Thread에서 Item을 발행하는 경우 꼭 SubjectSerialize 해주셔야 합니다. (참고링크)

뒤로가기 버튼 같은 경우 여러 Thread에서 호출될 일이 없기 때문에 굳이 Serialize 해주지 않아도 됩니다.

더 자세한 정보는 ReactiveX 홈페이지를 참조해주세요.

만들어진 Subject를 요리하고 구독하면!

이제 뒤로가기 버튼을 눌렀을 때 Itememit하는 부분을 작업했으니, Item을 구독하는 부분을 작업해 보도록 하죠!

핵심은 바로 buffer 입니다.

bufferItem을 지정한 개수만큼 쌓고 있다가, 지정한 개수가 되면 쌓은 Item을 한번에 emit합니다. buffercountskip Parameter를 받는데, 위 코드의 buffer(2, 1)두개를 쌓으면 Itememit하고, 기존에 쌓았던 데이터 중 한개를 건너뛰는걸 의미합니다. 만약에 buffer(2, 2) (buffer(2))로 작성하면 항상 새롭게 쌓여진 두개의 Itememit되겠죠.

이렇게 쌓은 데이터를 편의를 위해 Pair로 변환하여 onNext가 호출될 때 두 이벤트의 시간 차이가 특정시간보다 짧은 경우 앱을 종료하고, 아닌 경우에는 Toast 를 보여주도록 처리하면 끝입니다!

Rx로 코드를 이렇게 간단하게 짜니 Rx Single벙글~
요약하면 이렇습니다
아, 종료할때 Disposabledispose()하는걸 잊지 마세요!

글을 맺으며

비록 소소한 기능이긴 하지만, Rx를 활용해 조금 더 깔끔하게 코드를 작성할 수 있어서 뿌듯합니다. 읽어주셔서 감사합니다!

마지막으로 레이니스트에서는 Android 뿐만 아니라 개발 분야의 모든 직군을 채용중에 있습니다. 함께 기술적인 이슈들과, 제품에 대해 고민하며 더 나은 제품을 만들고 싶으신 분은 언제든지 지원해주세요! :D