在 Flutter 以 Fragment 方式嵌入到原生 Android 的混合项目中,全面屏设备侧滑返回或点击系统返回键时,应用直接退出(Activity onDestroy),而非预期行为:
FlutterFragment 默认未启用 shouldAutomaticallyHandleOnBackPressed,导致返回事件未传递给 Flutter。
事件链路实际为:
KEYCODE_BACK 发给 ActivityOnBackPressedCallback,系统直接执行默认行为PopScope、NavigatorObserver 等都不会被触发在创建 FlutterFragment 时,显式开启 shouldAutomaticallyHandleOnBackPressed(true):
flutterFragment = FlutterFragment.withCachedEngine(FLUTTER_ENGINE_ID)
.shouldAttachEngineToActivity(true)
.shouldAutomaticallyHandleOnBackPressed(true) // 关键:将返回事件交给 Flutter 处理
.build();
开启后:
OnBackPressedDispatcher 注册回调navigationChannel.popRoute(),把事件交给 Flutter 导航栈PopScope、 Navigator 等才能正常介入Transition.cupertino,让侧滑手势由 Flutter 的 Cupertino 转场接管,行为与系统一致PopScope 配合 canPop: false 拦截返回,实现「再按一次退出」// 首页
PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, result) async {
if (didPop) return;
if (!mounted) return;
final nav = Navigator.of(context);
if (nav.canPop()) {
nav.pop(); // 理论上不应出现
return;
}
// 首页:第一次提示,第二次退出
if (_lastBackAt != null && DateTime.now().difference(_lastBackAt!).inSeconds < 2) {
SystemNavigator.pop();
return;
}
_lastBackAt = DateTime.now();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('再按一次退出应用')),
);
},
child: Scaffold(...),
)
PopScope、NavigatorObserver 等处打 [BackDebug] 日志,发现按返回时没有任何 Flutter 日志,但 Activity 立刻 onDestroy,说明事件没到 Flutter。onBackPressed,说明是默认行为。问题在 Fragment 与 Activity 的返回事件分发上。ARG_SHOULD_AUTOMATICALLY_HANDLE_ON_BACK_PRESSED 默认为 false,需要显式设为 true。| 方面 | 说明 |
|---|---|
| FlutterFragment | 以 Fragment 嵌入时,务必在 builder 中启用shouldAutomaticallyHandleOnBackPressed(true) |
| 调试方式 | 若 Flutter 无响应,先在 Flutter 层加日志判断是否收到事件;若无,再检查 Android 层事件传递 |
| 文档 | Flutter 官方文档中 FlutterFragment 的「forwarding calls」部分需重点关注 |
| 平台差异 | MIUI 等定制系统可能改变默认行为,但根本仍在于 Fragment 是否注册了 OnBackPressedCallback |



