Android의 Back Press Handling: 본질, 메커니즘 및 구현

저자: IT Sectr 게시일: 2026-06-10 읽는 시간: 9 분

Back Press Handling은 Android에서 시스템 뒤로 가기 버튼을 가로채고 처리하여, 버튼을 눌렀을 때 어떤 동작이 수행되는지 결정하는 메커니즘입니다. Android Developers (2024)에 따르면, Android 11부터 기존의 onBackPressed() 메서드가 OnBackPressedDispatcher로 대체되었습니다. 새로운 API는 Activity뿐만 아니라 계층 구조의 모든 수준에 있는 구성 요소가 누름을 가로챌 수 있도록 합니다. 주요 차이점 — 우선순위가 있는 체인에서 여러 콜백 지원.

주요 포인트

  • Back Press Handling — Android에서 시스템 뒤로 가기 버튼을 처리하는 메커니즘
  • OnBackPressedDispatcher — 더 이상 사용되지 않는 onBackPressed()를 대체한 새로운 API
  • 콜백은 우선순위와 함께 등록되고 체인 순서로 실행됩니다
  • Jetpack Compose는 BackHandler를 사용하여 composable에서 누름을 가로챕니다
  • Support Library는 API Level 14까지 하위 호환성을 제공합니다

Back Press Handling이란

Back Press Handling은 사용자가 하드웨어 또는 소프트웨어 뒤로 가기 버튼을 눌렀을 때 어떤 일이 발생하는지 결정하는 Android의 시스템 메커니즘입니다. 상황에 따라 누름은 다음과 같은 작업을 수행할 수 있습니다: 현재 화면을 닫고 이전 화면으로 돌아가기, 키보드 숨기기, Drawer 또는 Bottom Sheet 닫기, 사용자가 루트 화면에 있는 경우 앱 종료.

뒤로 가기 버튼의 동작은 각 Android 버전과 함께 진화했습니다. Android 10은 제스처 내비게이션을 도입했고, Android 11은 OnBackPressedDispatcher를 표준 API로 도입했으며, Android 13은 향상된 predictive back gesture 지원을 가져와 시스템이 작업이 실제로 실행되기 전에 전환 애니메이션을 표시합니다. Google은 모든 장치에서 예측 가능하고 일관된 Back Press 동작을 향해 꾸준히 나아가고 있습니다.

뒤로 가기 버튼의 적절한 처리는 Android 앱에서 UX의 중요한 요소입니다. 사용자는 뒤로 가기를 누르면 내비게이션 스택의 이전 화면으로 돌아갈 것을 기대하며, 예기치 않게 앱이 종료되지 않을 것을 기대합니다. 이러한 기대를 위반하는 것은 Google Play에서 부정적인 리뷰와 낮은 평점의 주요 원인 중 하나입니다.

Back Press API의 진화: onBackPressed에서 OnBackPressedDispatcher로

Android의 Back Press API 역사는 플랫폼의 전반적인 진화를 반영합니다: Activity의 단순한 메서드에서 수명 주기 지원 및 Compose가 포함된 유연한 콜백 시스템으로. 개발의 세 단계를 살펴보겠습니다.

onBackPressed 시대 (API Level 1–30)

최초의 Android API부터 뒤로 가기 버튼은 Activity 클래스의 onBackPressed 메서드에서 처리되었습니다. 개발자는 이 메서드를 재정의하고 자신의 로직을 작성했습니다. 문제는 Fragment와 View가 누름을 가로챌 수 없다는 것이었습니다 — 모든 제어는 Activity를 통해 이루어졌습니다. 이로 인해 비대해진 Activity와 누가 누름을 처리해야 하는지 결정하기 위한 복잡한 if-else 체인이 발생했습니다.

OnBackPressedDispatcher의 등장 (Activity 1.0.0)

Activity 1.0.0(AndroidX)과 함께 Google은 OnBackPressedDispatcher를 도입했습니다. 이것은 Activity, Fragment, Dialog, 사용자 정의 View 등 모든 구성 요소에서 콜백을 수락하는 중앙 디스패처입니다. 콜백은 순서(priority를 통해)로 등록되고 동적으로 추가 또는 제거될 수 있습니다. OnBackPressedDispatcher는 이전 onBackPressed보다 먼저 호출되어 Activity가 처리하기 전에 누름을 가로챌 수 있습니다.

Predictive Back Gesture (Android 13+)

Android 13은 predictive back gesture를 도입했습니다 — 사용자가 제스처를 완료하기 전에 뒤로 가기 누름이 어디로 이어질지 보여주는 시스템 애니메이션입니다. 이 애니메이션을 지원하려면 개발자는 OnBackPressedDispatcher를 사용하고 isEnabled 속성을 통해 콜백이 시스템 애니메이션을 지원하는지 여부를 표시해야 합니다. 콜백이 predictive animation을 지원하지 않는 경우 시스템은 앱 컨텍스트와 일치하지 않을 수 있는 기본 애니메이션을 표시합니다.

API최소 SDKFragment 지원Predictive Back
onBackPressedAPI Level 1Activity를 통해아니요
OnBackPressedDispatcherActivity 1.0.0직접부분
OnBackPressedDispatcher + lifecycleActivity 1.3.0Lifecycle-aware전체

OnBackPressedDispatcher — 아키텍처 및 콜백 체인

OnBackPressedDispatcher는 새로운 Back Press API의 핵심입니다. 콜백 체인을 관리하며, 첫 번째 콜백이 이벤트를 처리할 때까지 순서대로 호출합니다. 어떤 콜백도 누름을 처리하지 않으면 디스패처는 기본 작업을 수행합니다 — Activity의 finish() 또는 Navigation Component의 popBackStack()을 호출합니다.

우선순위로 콜백 등록

콜백은 LifecycleOwner 및 OnBackPressedCallback 객체와 함께 addCallback을 통해 등록됩니다. 콜백에는 isEnabled 속성이 있습니다 — false로 설정하면 콜백이 건너뜁니다. 우선순위의 경우 0(가장 낮음)에서 Integer.MAX_VALUE까지 값을 전달할 수 있습니다. Fragment Activity Result API는 수명 주기에 바인딩된 콜백을 자동으로 등록하기 위해 이 메커니즘을 사용합니다.

kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val callback = object : OnBackPressedCallback(enabled = true) {
        override fun handleOnBackPressed() {
            if (isDrawerOpen) { closeDrawer() }
            else { isEnabled = false; onBackPressed() }
        }
    }
    onBackPressedDispatcher.addCallback(this, callback)
}

Lifecycle-aware 정리

콜백은 LifecycleOwner가 DESTROYED 상태로 전환될 때 자동으로 제거됩니다. 이는 화면 회전 중 콜백 누수의 오래된 문제를 해결합니다. 콜백이 Fragment에 추가된 경우 Fragment가 소멸될 때 제거됨이 보장됩니다. 콜백을 일시적으로 비활성화하려면 isEnabled 속성을 사용하십시오 — 제거 및 재등록 없이 전환할 수 있습니다.

호출 체인

호출 순서는 추가 순서의 역순입니다: 마지막으로 추가된 콜백이 먼저 제어권을 받습니다. 가장 깊이 중첩된 UI 요소(예: Fragment 내부의 Bottom Sheet)가 부모 Fragment보다 먼저 누름을 처리해야 하므로 이는 합리적입니다. 가장 깊은 콜백이 누름을 처리하지 않으면(isEnabled = false) 제어권은 체인의 다음 콜백으로 전달됩니다.

Fragment 및 대화상자에서의 Back Press

Fragment API는 requireActivity().onBackPressedDispatcher 메서드를 통해 OnBackPressedDispatcher와의 자체 통합을 제공합니다. Fragment 1.2.0부터 각 Fragment는 자체 콜백을 등록할 수 있으며, 이 콜백은 자동으로 Fragment 수명 주기에 바인딩되고 소멸될 때 제거됩니다.

Fragment의 콜백

Fragment에서 콜백 등록은 onCreate, onViewCreated 또는 View 자체에서 수행됩니다 — 중요한 것은 LifecycleOwner(Fragment)가 활성화되어 있다는 것입니다. Fragment가 STARTED 상태로 전환되면 콜백이 활성화되고 STOPPED되면 비활성화됩니다. 이렇게 하면 숨겨진 Fragment(ViewPager 내)가 뒤로 가기 누름을 처리하지 않습니다.

kotlin
class EditorFragment : Fragment() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val callback = object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                showDiscardDialog()
            }
        }
        requireActivity().onBackPressedDispatcher.addCallback(this, callback)
    }
}

Dialog 및 BottomSheetDialog

대화상자 및 BottomSheet는 닫기 위해 뒤로 가기 누름을 자동으로 가로챕니다. 닫기 전에 추가 작업을 수행해야 하는 경우 — 더 높은 우선순위로 콜백을 등록하십시오. 중요: Dialog에서 setCancelable(false)를 설정하면 콜백이 실행되지 않습니다 — 이것은 시스템 동작입니다.

Jetpack Compose에서의 Back Press Handling

Jetpack Compose는 BackHandler composable 함수를 통해 뒤로 가기 버튼을 처리하기 위한 선언적 API를 제공합니다. BackHandler는 enabled(부울 상태)와 onBack — 누를 때 호출되는 콜백을 허용합니다. enabled = false이면 누름이 체인의 더 아래로 전달됩니다.

Compose의 BackHandler

BackHandler는 부모 Activity의 OnBackPressedDispatcher에 자동으로 OnBackPressedCallback을 등록합니다. composable 수명 주기를 존중합니다: 구성을 떠날 때 콜백이 제거됩니다. enabled는 상태에 바인딩될 수 있습니다 — 예를 들어, 양식에 저장되지 않은 변경 사항이 있는 경우에만 확인 대화상자를 표시합니다.

kotlin
@Composable
fun EditScreen(hasUnsavedChanges: Boolean) {
    BackHandler(enabled = hasUnsavedChanges) {
        // Show confirmation dialog
    }

    Column {
        TextField(value = ..., onValueChange = ...)
    }
}

Compose의 Predictive Back

Compose의 Predictive back gesture는 Compose 1.5.0부터 지원됩니다. BackHandler는 장치에서 활성화된 경우 시스템 전환 애니메이션을 자동으로 처리합니다. 사용자 정의 predictive 애니메이션의 경우 predictiveBackHandler 수정자를 사용하여 0에서 1까지의 제스처 진행 상황을 반환합니다.

일반적인 오류 및 모범 사례

Back Press Handling은 단순해 보이지만 실제로 개발자는 여러 가지 체계적인 오류를 범합니다. Google의 권장 사항과 커뮤니티 경험을 기반으로 가장 일반적인 문제와 해결 방법을 살펴보겠습니다.

오류: 내비게이션 스택 확인 없이 finish() 호출

handleOnBackPressed에서 직접 finish()를 호출하면 내비게이션 스택에 백그라운드 화면이 있는 경우 예기치 않은 앱 종료가 발생할 수 있습니다. Activity를 닫기 전에 항상 Navigation Component 또는 Coordinator를 통해 NavController.backStack을 확인하십시오.

오류: 콜백 등록 시 수명 주기 무시

LifecycleOwner 없이 콜백을 등록하면(매개변수 없이 이전 addCallback 사용) 콜백이 영원히 유지되며 Activity가 이미 소멸된 경우 NullPointerException이 발생할 수 있습니다. 항상 LifecycleOwner와 함께 addCallback(this, callback)을 사용하십시오.

모범 사례: 모달 창에 대한 체인 중단

모달 창(Bottom Sheet, Dialog)의 경우 창이 표시될 때만 isEnabled = true로 설정하십시오. 창 상태를 확인하는 람다와 함께 addCallback을 사용하십시오. Navigation Component는 NavHost에 대해 이를 자동으로 관리합니다.

모범 사례: 더블 프레스 처리

빠른 더블 뒤로 가기 누름은 finish()의 이중 호출로 이어질 수 있습니다. 플래그 또는 throttleLast를 사용하여 500ms 이내의 반복 호출을 방지하십시오. Navigation Component는 이 상황을 기본적으로 처리하지만 사용자 정의 시나리오에서는 수동으로 보호를 구현해야 합니다.

kotlin
private var lastBackPressTime = 0L

override fun handleOnBackPressed() {
    val currentTime = System.currentTimeMillis()
    if (currentTime - lastBackPressTime > 500) {
        lastBackPressTime = currentTime
        navigateBack()
    }
}

자주 묻는 질문

onBackPressed가 더 이상 사용되지 않는 이유는 무엇인가요?

onBackPressed는 Activity 수준에서만 작동하기 때문에 Android 11에서 더 이상 사용되지 않습니다. OnBackPressedDispatcher는 수명 주기 지원이 있는 단일 메커니즘을 통해 모든 구성 요소(Fragment, Dialog, View)가 누름을 가로챌 수 있도록 합니다.

뒤로 가기 누름과 스와이프 제스처를 어떻게 구분하나요?

Android 시스템은 애플리케이션이 수신하기 전에 가장자리에서 스와이프 제스처를 시스템 뒤로 가기 누름으로 변환합니다. OnBackPressedDispatcher 수준에서는 이 두 이벤트를 구분할 수 없습니다 — 둘 다 handleOnBackPressed로 도착합니다.

제스처 기반 장치에서 뒤로 가기 버튼을 지원해야 하나요?

, OnBackPressedDispatcher 처리는 세 개의 버튼이 있는 장치와 제스처 내비게이션이 있는 장치에서 동일합니다. 가로채기 코드는 내비게이션 유형에 의존하지 않습니다 — 시스템 자체가 제스처를 디스패처 호출로 변환합니다.

에뮬레이터에서 predictive back gesture를 테스트하려면 어떻게 해야 하나요?

Android 13+ 에뮬레이터의 Developer Options에서 predictive back을 활성화하십시오. ADB를 사용하십시오: `adb shell settings put global enable_back_animation 1`. 활성화하면 시스템 애니메이션이 뒤로 가기 누름 시 전환 미리보기를 표시합니다.

콜백이 호출되지 않으면 어떻게 해야 하나요?

두 가지 조건을 확인하십시오: LifecycleOwner가 STARTED 또는 RESUMED 상태여야 하고 콜백의 isEnabled가 true여야 합니다. 두 조건이 모두 충족되면 콜백이 올바른 OnBackPressedDispatcher에 추가되었는지 확인하십시오 — Fragment에서 requireActivity().onBackPressedDispatcher를 사용하십시오.

요약

  • Back Press Handling — Android에서 시스템 뒤로 가기 버튼을 처리하는 메커니즘
  • OnBackPressedDispatcher — Android 11부터 onBackPressed()를 대체한 최신 API
  • 콜백은 LifecycleOwner와 함께 addCallback을 통해 등록되고 자동으로 정리됩니다
  • 호출 체인 — isEnabled=true인 마지막 추가 콜백이 누름을 먼저 처리합니다
  • Fragment에서 콜백은 수명 주기에 바인딩되고 프래그먼트가 숨겨지면 비활성화됩니다
  • Jetpack Compose는 선언적 처리를 위해 BackHandler composable을 사용합니다
  • Predictive back gesture — Android 13+에서 사용 가능한 시스템 전환 애니메이션

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기