androidkotlinnavigationdeprecation-warningandroid-tiramisu

onBackPressed() is deprecated. What is the alternative?


I have upgraded targetSdkVersion and compileSdkVersion to 33.

I am now getting a warning telling me that onBackPressed is deprecated.

I see suggestions to use android.window.OnBackInvokedCallback or androidx.activity.OnBackPressedCallback to handle back navigation instead. Can anyone can help me use the updated method?

Example

onBackPressedDeprecated

Use Case

I use if (isTaskRoot) {} inside the onBackPressed() method to check whether the activity is the last one on the activity stack.

override fun onBackPressed() {
    if (isTaskRoot) { // Check whether this activity is last on the activity stack. (Check whether this activity opened from a Push Notification.)
        startActivity(Intent(mContext, Dashboard::class.java))
        finish()
    } else {
        finishWithResultOK()
    }
}

Solution

  • According your API level register:

    This requires to at least use appcompat:1.6.0-alpha03; the current is 1.6.0-alpha04:

     implementation 'androidx.appcompat:appcompat:1.6.0-alpha04'
    
    // kotlin
    import androidx.activity.addCallback
    
    if (BuildCompat.isAtLeastT()) {
        onBackInvokedDispatcher.registerOnBackInvokedCallback(
            OnBackInvokedDispatcher.PRIORITY_DEFAULT
        ) {
            // Back is pressed... Finishing the activity
            finish()
        }
    } else {
        onBackPressedDispatcher.addCallback(this /* lifecycle owner */, object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                // Back is pressed... Finishing the activity
                finish()
            }
        })
    }
    
    // ====================================================
    /* Or for lambda simplicity: */
    // ====================================================
    if (BuildCompat.isAtLeastT()) {
        onBackInvokedDispatcher.registerOnBackInvokedCallback(
            OnBackInvokedDispatcher.PRIORITY_DEFAULT
        ) {
            // Back is pressed... Finishing the activity
            finish()
        }
    } else {
        onBackPressedDispatcher.addCallback(this /* lifecycle owner */) {
            // Back is pressed... Finishing the activity
            finish()
        }
    }
    
    
    

    UPDATE:

    Thanks to @ianhanniballake comment; you can just use OnBackPressedDispatcher even in API level 33+

    The OnBackPressedDispatcher is already going to be using the Android T specific API internally when using Activity 1.6+,

    So, you can just do:

    // kotlin
    import androidx.activity.addCallback
    
    onBackPressedDispatcher.addCallback(this /* lifecycle owner */, object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            // Back is pressed... Finishing the activity
            finish()
        }
    })
    
    // ====================================================
    /* Or for lambda simplicity: */
    // ====================================================
    onBackPressedDispatcher.addCallback(this /* lifecycle owner */) {
        // Back is pressed... Finishing the activity
        finish()
    }
    
    
    // java
    import androidx.activity.OnBackPressedCallback;
    
    getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
        @Override
        public void handleOnBackPressed() {
            // Back is pressed... Finishing the activity
            finish();
        }
    });
    

    Note that you shouldn't override the onBackPressed() as that will make the onBackPressedDispatcher callback not to fire; check this answer for clarifying that.