onBackPressed() is deprecated: how to properly handle the "Back" button in Android
If you've ever written Android code in Kotlin, you've likely encountered the onBackPressed() method. Until recently, this was the standard way to intercept the system "Back" button press. But in the latest versions of Android Studio, you'll notice this method is struck through and marked with the @Deprecated annotation. This raises a natural question: "onBackPressed() is deprecated. What is the alternative?" — a question that has garnered thousands of views on Stack Overflow.
In this article, we'll break down why Google decided to abandon the old approach and show you, with real Kotlin code examples, how to properly handle the "Back" button press now. You'll learn about OnBackPressedDispatcher, OnBackPressedCallback, and how to integrate this with the Activity and Fragment lifecycle. Let's go!
Why did onBackPressed() become deprecated?
The main reason is Android's architectural evolution. The old onBackPressed() method was tightly coupled to Activity. It didn't account for fragments, didn't support modern patterns (MVVM, Clean Architecture), and often led to confusion when multiple components tried to handle the same event. Google moved toward delegation: now, "back" handling is passed to a special dispatcher — OnBackPressedDispatcher.
This change is part of a broader strategy to simplify navigation and improve Jetpack support. Now you can add multiple callbacks that work consistently and are lifecycle-aware. If you use the Navigation Component, "back" handling is automatically delegated to the navigation graph.
What replaced it: OnBackPressedDispatcher
Starting with Activity 1.0.0 (part of AndroidX), Google introduced a new API. The main components are:
- OnBackPressedDispatcher — the central dispatcher that manages all callbacks.
- OnBackPressedCallback — a class you extend to define your own handling logic.
- LifecycleOwner — binding to the lifecycle (Activity or Fragment).
Instead of overriding an Activity method, you register a callback with the dispatcher. The dispatcher itself decides which callback to execute first (LIFO principle — the last added is handled first).
Basic implementation in Activity
Let's start with a simple example. Suppose you want to show a confirmation dialog when the "Back" button is pressed, to prevent the user from accidentally closing the app.
Old way (deprecated):
// We don't do this anymore!@Deprecatedoverride fun onBackPressed() { showExitDialog()}New way with OnBackPressedDispatcher:
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main)
// Register the callback onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { // Your custom logic showExitDialog() } }) }
private fun showExitDialog() { AlertDialog.Builder(this) .setTitle("Exit") .setMessage("Are you sure you want to exit?") .setPositiveButton("Yes") { _, _ -> finish() } .setNegativeButton("No", null) .show() }}Note the true parameter in the OnBackPressedCallback(true) constructor. This is