调用onBackPressed()是否需针对API 33及以下版本做差异化处理?
问题背景
我用onBackPressedDispatcher.addCallback()处理返回键事件,没有重写onBackPressed()方法,但会在需要条件性触发默认返回操作时调用onBackPressed()。
但Android官方文档里有这么一句:
在Android 12(API级别32)及更低版本中,无论是否注册了OnBackPressedCallback实例,onBackPressed都会被调用。
这让我搞不清楚是不是得针对API 32及以下版本做特殊处理,但实际测试和调试后发现,API 32和API 33的行为完全一致。两个版本里ComponentActivity的onBackPressed()实现都是:
public void onBackPressed() { getOnBackPressedDispatcher().onBackPressed(); }
OnBackPressedDispatcher的onBackPressed()实现则是:
public void onBackPressed() { Iterator<OnBackPressedCallback> iterator = mOnBackPressedCallbacks.descendingIterator(); while (iterator.hasNext()) { OnBackPressedCallback callback = iterator.next(); if (callback.isEnabled()) { callback.handleOnBackPressed(); return; } } if (mFallbackOnBackPressed != null) { mFallbackOnBackPressed.run(); } }
原因解析
你的猜测完全正确:文档的表述混淆了系统API版本和androidx.appcompat:appcompat库的版本,而非运行时的Android系统版本。
在早期的AppCompat库版本(比如appcompat:1.3.x及更早)中,ComponentActivity的onBackPressed()实现并没有完全委托给OnBackPressedDispatcher,而是存在独立的处理逻辑,这才会出现“无论是否注册Callback都会调用onBackPressed()”的情况。后来AppCompat库更新后,统一将onBackPressed()的实现改为完全委托给Dispatcher,这个修改覆盖了所有系统API级别(包括API 32及以下)。
结论与建议
- 不需要针对API 32及以下系统版本做特殊处理,只要你用的是较新版本的
androidx.appcompat:appcompat库(推荐1.4.0及以上),onBackPressed()的行为在所有API级别上都是一致的:优先执行已注册的OnBackPressedCallback,没有可用Callback时才会执行 fallback 逻辑。 - 既然官方已经弃用
ComponentActivity的onBackPressed()方法,建议直接调用onBackPressedDispatcher.onBackPressed()来触发默认返回逻辑,避免依赖已弃用的API。
内容的提问来源于stack exchange,提问作者Doron Ben-Ari

