뒤로 탐색 기능은 사용자가 이전에 방문한 화면 기록을 통해 뒤로 이동하는 기능입니다. 모든 Android 기기는 이 유형의 탐색을 위해 뒤로 버튼을 제공하므로 앱 UI에 뒤로 버튼을 추가하면 안 됩니다. 사용자의 Android 기기에 따라 이 버튼은 물리적 버튼 또는 소프트웨어 버튼이 될 수 있습니다.
Android는 사용자가 애플리케이션을 탐색할 때 대상의 백 스택을 유지합니다. 이를 통해 일반적으로 Android를 사용하면 뒤로 버튼을 누를 때 이전 대상으로 적절하게 이동할 수 있습니다. 하지만, 최상의 사용자 환경을 제공하기 위해 앱에서 뒤로 이동하는 동작을 자체적으로 구현해야 하는 경우도 있습니다. 예를 들어, WebView
를 사용할 때는 기본 뒤로 버튼 동작을 재정의하여 사용자에게 앱의 이전 화면 대신 웹 방문 기록을 통해 뒤로 이동하도록 하는 것이 좋습니다.
맞춤 뒤로 탐색 구현
FragmentActivity
와 AppCompatActivity
의 기본 클래스인 ComponentActivity
를 사용하면 OnBackPressedDispatcher
(getOnBackPressedDispatcher()
를 호출하여 가져옴)를 사용하여 뒤로 버튼의 동작을 제어할 수 있습니다.
OnBackPressedDispatcher
는 뒤로 버튼 이벤트가 하나 이상의 OnBackPressedCallback
객체로 전달되는 방법을 제어합니다. OnBackPressedCallback
의 생성자는 초기 사용 설정 상태를 나타내는 부울 값을 사용합니다. 콜백이 사용 설정된 때만(즉,
isEnabled()
가 true
를 반환) 디스패처가 콜백의 handleOnBackPressed()
를 호출하여 뒤로 버튼 이벤트를 처리합니다. 사용 설정 상태는 setEnabled()
를 호출하여 변경할 수 있습니다.
콜백은 addCallback
메서드를 통해 추가됩니다. LifecycleOwner
를 취하는 addCallback()
메서드를 사용하는 것이 좋습니다.
이렇게 하면 LifecycleOwner
가 Lifecycle.State.STARTED
일 때만 OnBackPressedCallback
이 추가되도록 할 수 있습니다.
또한 활동은 연결된 LifecycleOwner
가 제거될 때 등록된 콜백을 삭제합니다. 이는 메모리 누수를 방지하며, 전체 기간이 활동보다 짧은 프래그먼트 또는 기타 수명 주기 소유자에 사용하기 적합합니다.
다음은 콜백 구현의 예입니다.
Kotlin
class MyFragment : Fragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // This callback will only be called when MyFragment is at least Started. val callback = requireActivity().onBackPressedDispatcher.addCallback(this) { // Handle the back button event } // The callback can be enabled or disabled here or in the lambda } ... }
자바
public class MyFragment extends Fragment { @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); // This callback will only be called when MyFragment is at least Started. OnBackPressedCallback callback = new OnBackPressedCallback(true /* enabled by default */) { @Override public void handleOnBackPressed() { // Handle the back button event } }; requireActivity().getOnBackPressedDispatcher().addCallback(this, callback); // The callback can be enabled or disabled here or in handleOnBackPressed() } ... }
addCallback()
을 통해 여러 개의 콜백을 제공할 수 있습니다.
이렇게 하면 콜백은 추가된 순서의 역순으로 호출되며 마지막으로 추가된 콜백이 뒤로 버튼 이벤트를 처리할 기회를 처음으로 얻게 됩니다. 예를 들어, one
, two
및 three
라는 이름의 콜백 세 개를 순서대로 추가하면 각각 three
, two
및 one
의 순서로 호출됩니다.
콜백은 책임 연쇄(Chain of Responsibility) 패턴을 따릅니다. 체인의 각 콜백은 앞의 콜백이 사용 설정되지 않은 경우에만 호출됩니다. 즉, 앞의 예에서 콜백 two
는 콜백 three
가 사용 설정되지 않은 경우에만 호출됩니다. 콜백 one
은 콜백 two
가 사용 설정되지 않은 경우에만 호출되며 이런 방식으로 이어집니다.
콜백은 addCallback()
을 통해 추가할 때 LifecycleOwner
가 Lifecycle.State.STARTED
상태에 진입할 때까지 책임 연쇄에 추가되지 않습니다.
여러 개의 다른 중첩된 수명 주기 소유자에 등록된 콜백이 있다면 위에서 설명한 순서를 유지하는 것이 특히 중요하므로 OnBackPressedCallback
의 사용 설정 상태를 변경하는 것은 일시적인 변경이 좋습니다.
그러나 OnBackPressedCallback
을 전체적으로 삭제하려는 경우 remove()
를 호출해야 합니다.
하지만, 콜백은 연결된 LifecycleOwner
가 제거될 때 자동으로 삭제되므로 일반적으로 필수사항은 아닙니다.
onBackPressed() 활동
onBackPressed()
를 사용하여 뒤로 버튼 이벤트를 처리하고 있다면 이 메서드 대신 OnBackPressedCallback
을 사용하는 것이 좋습니다.
하지만 변경이 불가능하다면 다음 규칙이 적용됩니다.
addCallback
을 통해 등록된 모든 콜백은super.onBackPressed()
를 호출할 때 평가됩니다.- Android 12(API 수준 32) 이하에서는
OnBackPressedCallback
의 등록된 인스턴스와 관계없이onBackPressed
가 항상 호출됩니다.