You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 13+中使用registerOnBackInvokedCallback替代super.onBackPressed()的正确方法

适配Android 13+返回键的正确实现

你在OnBackInvokedCallback中调用getOnBackPressedDispatcher().onBackPressed()是错误的,这会触发无限循环——因为API 33+中onBackPressed()会直接触发你注册的OnBackInvokedCallback,导致回调反复执行,最终抛出StackOverflowError。

原代码逻辑的正确替代

你原来的代码逻辑是:设置标记dontStopMusicOnPause = true,再执行系统默认返回操作(优先弹出Fragment回退栈,无回退栈则关闭Activity)。对应OnBackInvokedCallback的正确写法如下:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
    OnBackInvokedCallback callback = () -> {
        // 执行自定义标记逻辑
        dontStopMusicOnPause = true;
        
        // 完全模拟super.onBackPressed()的默认行为
        if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
            // 存在Fragment回退栈,弹出顶部Fragment
            getSupportFragmentManager().popBackStack();
        } else {
            // 无回退栈,关闭当前Activity
            finish();
        }
    };
    getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
        OnBackInvokedDispatcher.PRIORITY_DEFAULT,
        callback
    );
    
    // 绑定生命周期注销回调,避免内存泄漏
    getLifecycle().addObserver(new DefaultLifecycleObserver() {
        @Override
        public void onDestroy(@NonNull LifecycleOwner owner) {
            getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(callback);
        }
    });
}

为什么不能直接调用finish()?

直接调用finish()会跳过Fragment回退栈的处理,而原super.onBackPressed()会优先处理Fragment回退逻辑,只有当栈为空时才会关闭Activity。上面的代码完整复现了这一系统默认行为。

低版本兼容方案

如果需要兼容Android 12及以下版本,保留原onBackPressed()实现即可,系统会自动在低版本走旧逻辑,高版本走OnBackInvokedCallback:

@Override
public void onBackPressed() {
    dontStopMusicOnPause = true;
    super.onBackPressed();
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // ...其他初始化代码
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        OnBackInvokedCallback callback = () -> {
            dontStopMusicOnPause = true;
            if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
                getSupportFragmentManager().popBackStack();
            } else {
                finish();
            }
        };
        getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
            OnBackInvokedDispatcher.PRIORITY_DEFAULT,
            callback
        );
        getLifecycle().addObserver(new DefaultLifecycleObserver() {
            @Override
            public void onDestroy(@NonNull LifecycleOwner owner) {
                getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(callback);
            }
        });
    }
}

内容的提问来源于stack exchange,提问作者NullPointerException

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.02 03:47:30