안드로이드 앱에서 제일 처음의 화면에서 뒤로 가기를 눌렀을 때 앱이 바로 종료되지 않고, 일정 시간 내에 뒤로 가기 버튼을 한번 더 눌렀을 때 앱이 종료되는 것을 많이 볼 수 있습니다. 이번 포스팅에서는 안드로이드 Jetpack의 OnBackPressedDispatcher를 활용해서 뒤로 가기를 두 번 눌렀을 때 앱이 종료되는 기능을 구현하겠습니다.

1. OnBackPressedDispatcher란?
onBackPressedDispatcher는 안드로이드 Jetpack 컴포넌트 중 하나로, 액티비티 뒤로 가기 버튼의 동작을 관리하고 있습니다. 기존에는 onBackPressed() 함수를 오버라이드해서 뒤로 가기 기능을 커스텀할 수 있었지만, API 33 이후부터 해당 함수가 Deprecated 되면서 onBackPressedDispatcher로 대체되었습니다.

2. OnBackPressedDispatcher를 사용해서 뒤로 가기 구현하기
onBackPressedDispatcher를 사용해서 뒤로 가기를 사용하기 위해서는 OnBackPressedCallback의 구현체를 사용해야 합니다. OnBackPressedCallback는 추상클래스로써 직접 구현체를 만들기 도하지만 익명 객체로 생성하여 구현하면 편리합니다.
2-1. OnBackPressedCallback 객체 생성하기
아래 코드는 OnBackPressedCallback을 익명 객체로 생성하고, 뒤로 가기를 눌렀을 때 실행될 기능을 handleOnBackPressed() 함수에 구현한 모습입니다. 또한, 익명 객체로 생성 시 OnBackPressedCallback이 사용 가능한지에 대한 변수를 생성자에 true로 전달했습니다.
private var backKeyPressedTime = 0L
private val onBackPressedCallback: OnBackPressedCallback = object: OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
if (System.currentTimeMillis() > backKeyPressedTime + 2000) {
backKeyPressedTime = System.currentTimeMillis()
Toast.makeText(this@MainActivity, "뒤로 버튼을 한번 더 누르시면 종료됩니다.", Toast.LENGTH_SHORT).show()
} else {
finish()
}
}
}
해당 코드는 뒤로 가기 버튼을 한번 누르면 Toast 팝업창을 보여주고, 2초 안에 뒤로 가기를 한번 더 누르면 앱이 종료되는 로직입니다.
2-2. OnBackPressedCallback를 OnBackPressedDispatcher에 제공하기
이제 위에서 만든 onBackPressedCallback 객체를 OnBackPressedDispatcher에 제공하겠습니다. 아래 코드 예제처럼 OnBackPressedDispatcher의 addCallback 함수를 사용해서 콜백 함수를 등록할 수 있습니다. 뒤로 가기 버튼을 눌렀을 때 토스트 팝업창이 나오며 2초 안에 다시 눌렀을 때는 앱이 종료됩니다.
class MainActivity : ComponentActivity() {
private var backKeyPressedTime = 0L
private val onBackPressedCallback: OnBackPressedCallback = object: OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
if (System.currentTimeMillis() > backKeyPressedTime + 2000) {
backKeyPressedTime = System.currentTimeMillis()
Toast.makeText(this@MainActivity, "뒤로 버튼을 한번 더 누르시면 종료됩니다.", Toast.LENGTH_SHORT).show()
} else {
finish()
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
onBackPressedDispatcher.addCallback(this, onBackPressedCallback)
...
}
}
3. OnBackPressedDispatcher 정리
이번 포스팅에서는 뒤로 가기 두 번 눌렀을 때 앱이 종료되는 예제와 함께 OnBackPressedDispatcher의 사용 방법에 대해 살펴보았습니다. 안드로이드 API 33 이상부터 onBackPressed() 함수가 Deprecated 되면서 OnBackPressedDispatcher를 사용해야 합니다. 그리고 예제에서 설명한 기능을 구현하면 사용자의 실수로 인한 앱 종료를 예방하면서 사용자 경험 개선에도 도움이 된다고 생각합니다.