Photo by Xan White on Unsplash
As we know, with every release, Android deprecates some APIs and introduces new ones to replace the old ones. Starting from Android 13, Google has deprecated the onBackPressed()
functions. Why has this been deprecated? What changes do we need to make after this change?In this article, we’ll briefly delve into all these questions.
Why onBackPressed is deprecated?
To understand why onBackPressed()
is deprecated we first need to understand the evolution of back buttons in android. It started with physical back button and over the years google has completely removed the buttons with gesture navigation to fully utilise the device screen.
Back Button Evolution
With gesture navigation change google team was able to add predictive animation on recent and home button i.e. when you go to recent screen by swiping up you get the animation showing what will be destination for this action.
Swipe up animation for Recent screen
This is possible because the system knows what is happening ahead of time, allowing the OS to provide predictive feedback. However, this is not possible in the case of the back button, as the system doesn’t know what will happen when it is pressed. The reason for this is that the system doesn’t know whether the app will handle the back press or if the system should handle it. As a result, the system cannot show the forward destination.
Starting from Android 13, apps should inform the system whether they will handle the back press or if the system should handle it.
Introducing Predictive back animation
Google thought that if it knew that a back button would exit the app, it could provide a slight animation to warn the user beforehand.
This would help users differentiate between an app internal back (to a previous screen) and actually exiting the app.
In Android 13, this is possible if:
- The app adopts Predictive Back in the code and no longer uses
onBackPressed()
. - The app opts-in to Predictive Back by declaring
android:enableOnBackInvokedCallback="true"
in the application section of the AndroidManifest.xml file. - The Predictive back animations feature is turned on in the Developer Options.
What changes do we need to make after this change?
According to the documentation, to support this ahead of time model, Google introduced new API called OnBackInvokedCallback
. This interface has only one method onBackInvoked()
, which will be called instead of legacy onBackPressed()
methods from your activities and dialogues. New application will stop receiving key back events. If your app uses AndroidX
dependency you can use OnBackPressedDispatcher
. Let’s take a look at both approaches.
Migrate from unsupported back navigation APIs to platform APIs
If your application is unable to utilize AndroidX libraries and currently implements or references custom back navigation using unsupported APIs, it’s imperative to transition to the OnBackInvokedCallback
platform API.
Follow these precise steps to seamlessly migrate from unsupported APIs to the platform API:
- Implement the new
OnBackInvokedCallback
API for devices running Android 13 or later, while continuing to rely on the unsupported APIs for devices running Android 12 or earlier. - Register your custom back logic within the
OnBackInvokedCallback
usingonBackInvokedDispatcher
. This will ensure that the current activity isn’t prematurely finished, granting your callback the opportunity to respond to the Back action once the user completes the system Back navigation. - Responsibly unregister the
OnBackInvokedCallback
when it’s appropriate to cease intercepting the back gesture. Failure to do so may result in an unfavorable user experience, such as being ‘stuck’ between views, compelling them to force quit your application.
Here is an example in which we are showing a dialogue to warn user that they will loose the entered data in edit text. This is how our old code looks:
Job Offers
override fun onBackPressed() { if (editText.isNullOrEmpty().not()) { showDialog() } else { super.onBackPressed() } } private fun showDialog(){ MaterialAlertDialogBuilder(this).apply { setTitle("Are you sure?") setMessage("you'll loose the data") setPositiveButton("Yes") { _, _ -> finish() } setNegativeButton("No", null) show() } }
After using new Platform API our code looks like this:
private val mBackInvokedCallback = OnBackInvokedCallback { showDialog() } private val mCallbackRegistered = false @Override fun onCreate() { if (BuildCompat.isAtLeastT()) { binding.editText.doAfterTextChanged { text -> updateCallback(text) } } } fun updateCallback(text: String) { if(text.isNul1OrEmpty() && mCallbackRegistered) { onBackInvokedDispatcher.unregisterOnBackInvokedCallback(mBackInvokedCallback) mCallbackRegistered = false } else { onBackInvokedDispatcher.registerOnBackInvokedCallback(mBackInvokedCallback, OnBackInvokedDispatcher.PRIORITY_DEFAULT) mCallbackRegistered = true } }
In above example we register OnBackInvokedCallback
based on the text state. If OnBackInvokedCallback
is not registered then it will call the system back press.
Note: You have to opt-in to supporting the predictive back gesture. To opt-in, in
AndroidManifest.xml, in the
<application> tag, set the
android:enableOnBackInvokedCallback flag to
true. If you don’t provide this value, it defaults to
false and Ignores
OnBackInvokedCallback
Migrate from unsupported back navigation APIs to AndroidX APIs
If your application utilize AndroidX libraries and currently implements or references custom back navigation using unsupported APIs, it’s imperative to transition your system Back handling logic to AndroidX’s OnBackPressedDispatcher
with an implementation of OnBackPressedCallback
. To use OnaBackPressedDispatcher
make sure you upgrade to AndroidX Activity 1.6.0-alpha05.
Note: This is the recommended way to handle Back press because this is backward compatible and you don’t have to maintain different logic from Android 13. But there will be some instances where you can’t use
OnBackPressedDispatcher e.g. custom views. For that you have to use the new Platform API.
We will take previous example and will use OnBackPressedDispatcher
to show confirmation dialog:
private val callback = object : OnBackPressedCallback(enabled = false) { override fun handleOnBackPressed() { showDialog() } } @Override fun onCreate() { // adding OnBackPressedCallback listener. onBackPressedDispatcher.addCallback(this,callback) binding.editText.doAfterTextChanged { text -> callback.isEnabled = !text.isNul1OrEmpty() } }
Notice how we are passing enabled=false
in OnBackPressedCallback
which ensures that we are giving back press control to system initially and changing it based on text input.
Note: We don’t have to opt-in for
android:enableOnBackInvokedCallback to receive back press call inside
OnBackPressedCallback. It will always receive the callback regardless the value of
enableOnBackInvokedCallback.
That’s it!!!
And here’s the cherry on top! With the final release of Android 13, you have the power to test the all-new ‘back-to-home animation.’ Here’s how to unlock this feature:
- Access Developer Options: Navigate to your device’s settings and tap on ‘System.’ From there, find and select ‘Developer options.’
- Activate Predictive Back Animations: Within ‘Developer options,’ locate and enable ‘Predictive back animations.’
- Witness the Magic: Fire up your updated app and give the back gesture a whirl. Behold the mesmerizing ‘back-to-home animation’ in action.
Simple, yet captivating! Enjoy exploring this exciting feature.
This article was previously published on proandroiddev.com