Skip to content

[Android] Predictive back state is lost when a retained FlutterEngine attaches to a new Activity #192284

Closed

Description

@xianjianlf2

Steps to reproduce

This is a remaining case of #159158. The earlier fix restores the predictive-back state from savedInstanceState for an engine referenced by getCachedEngineId(). It does not cover a retained engine returned by provideFlutterEngine(), or a new Activity created without saved instance state after the previous task was removed.

The issue is still present on Flutter 3.44.1 and on current master (abee5f5d5648fb6bb6ad55a5b153188e5dc9f055). I could not find an open issue or pull request covering this remaining case.

  1. Enable android:enableOnBackInvokedCallback="true".
  2. Create one process-scoped FlutterEngine and return it from FlutterActivity.provideFlutterEngine().
  3. Start Dart after the first Activity has attached to the engine.
  4. Show a PopScope(canPop: false) so the framework sends SystemNavigator.setFrameworkHandlesBack(true).
  5. Destroy and remove the Activity task while keeping the process and engine alive.
  6. Start a new Activity backed by the same engine. Confirm that the Dart isolate and route were retained.
  7. Press system Back or complete a predictive-back gesture.

Expected results

The new Activity registers its OnBackInvokedCallback. Back is delivered to Flutter, and the retained PopScope receives the attempted pop.

Actual results

The old Activity unregisters its callback when it is destroyed. The new Activity starts with frameworkHandlesBack == false, and the retained route does not resend the unchanged state. Back bypasses Flutter and closes the Activity.

On a physical Pixel 10a running Android 16 / API 36, the same-process reproduction produced:

ENGINE_CREATED pid=12846 engine=149542612
ACTIVITY_CREATED activity=38678894 engine=149542612
FRAMEWORK_HANDLES_BACK value=true activity=38678894
ACTIVITY_DESTROYED activity=38678894
ACTIVITY_CREATED activity=97584968 engine=149542612
# No FRAMEWORK_HANDLES_BACK call for the replacement Activity.
# Pressing Back destroys activity=97584968; PopScope receives no callback.

The platform channel currently discards messages while no PlatformMessageHandler is attached, and it does not retain the most recent SystemNavigator.setFrameworkHandlesBack value for a replacement handler. The Bundle-based restoration in FlutterActivity is not engine-scoped and is conditional on a cached-engine ID.

Code sample

Code sample
import 'package:flutter/material.dart';

void main() => runApp(const ReproApp());

class ReproApp extends StatelessWidget {
  const ReproApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: PopScope<void>(
        canPop: false,
        onPopInvokedWithResult: (didPop, result) {
          debugPrint('POP_INVOKED didPop=$didPop');
        },
        child: const Scaffold(
          body: Center(child: Text('Retained engine back repro')),
        ),
      ),
    );
  }
}
public final class MainApplication extends FlutterApplication {
  private FlutterEngine engine;

  @Override
  public void onCreate() {
    super.onCreate();
    engine = new FlutterEngine(this);
  }

  public FlutterEngine getEngine() {
    return engine;
  }
}
public final class MainActivity extends FlutterActivity {
  @Override
  public FlutterEngine provideFlutterEngine(@NonNull Context context) {
    return ((MainApplication) getApplication()).getEngine();
  }

  @Override
  public boolean shouldDestroyEngineWithHost() {
    return false;
  }

  @Override
  public void configureFlutterEngine(@NonNull FlutterEngine engine) {
    super.configureFlutterEngine(engine);
    if (!engine.getDartExecutor().isExecutingDart()) {
      engine.getDartExecutor().executeDartEntrypoint(
          DartExecutor.DartEntrypoint.createDefault());
    }
  }
}

The Activity can expose a debug-only action that calls finishAndRemoveTask(). Relaunch it immediately and verify that the PID and FlutterEngine identity are unchanged before pressing Back. A foreground service can also keep the process alive while the task is removed.

Screenshots or Video

Not applicable. The lifecycle identities and back callback are captured in the logs above.

Logs

Logs
Pixel 10a, Android 16 / API 36
Flutter 3.44.1, engine c416acfeb8

Before replacement:
FRAMEWORK_HANDLES_BACK value=true activity=38678894

After replacement with the same PID and engine:
ACTIVITY_CREATED activity=97584968 engine=149542612

After system Back:
ACTIVITY_DESTROYED activity=97584968
# No POP_INVOKED log.

Flutter Doctor output

Doctor output
[!] Flutter (Channel stable, 3.44.1, on macOS 26.3 25D125 darwin-arm64, locale zh-Hans-CN)
    • Framework revision 924134a44c
    • Engine revision c416acfeb8
    • Dart version 3.12.1
    • DevTools version 2.57.0

[✓] Android toolchain - develop for Android devices (Android SDK version 36.1.0)
    • Platform android-36.1, build-tools 36.1.0
    • Java version OpenJDK Runtime Environment (build 21.0.10+-117844308-b1163.108)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 26.6)
[✓] Chrome - develop for the web
[✓] Connected device
    • Pixel 10a • android-arm64 • Android 16 (API 36)
[✓] Network resources

The local PATH warning and unrelated local-network iOS discovery warnings were omitted.

Activity

  1. suryaKommana2662 commented on Sep 4, 2026

    @suryaKommana2662
    Contributor

    @xianjianlf2 Thanks for the detailed report and for providing a fix in #192286. I noticed that the issue was reproduced on Flutter 3.44.1. Could you please verify whether the issue is still reproducible on the latest Flutter stable release (3.47.2) and confirm the result?

  2. added
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    and removed
    in triagePresently being triaged by the triage team
    on Sep 4, 2026
  3. xianjianlf2 commented on Sep 4, 2026

    @xianjianlf2
    ContributorAuthor

    Thanks for checking. I confirmed that this is still reproducible on Flutter 3.47.2 stable (d3b14c8769, engine a804b26164) on a physical Samsung SM-A376B running Android 16 / API 36.

    Using the same retained-engine reproduction, I verified that the process PID and FlutterEngine identity remained unchanged after removing the original task and launching a replacement Activity. The replacement Activity did not receive the existing frameworkHandlesBack state.

    I repeated both cases three times:

    • System Back: 3/3 closed the replacement Activity.
    • Completed predictive-back gesture: 3/3 closed the replacement Activity.
    • PopScope received no callback in all six baseline attempts.

    I also tested the patch from #192286 for three complete cycles. The replacement Activity received the retained state, both System Back and completed predictive-back gestures reached PopScope with didPop=false, and cancelled predictive-back gestures left the Activity in the foreground without invoking the callback.

    So the issue is not fixed in Flutter 3.47.2, and the proposed patch resolves it in this physical-device test.

  4. removed
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Sep 4, 2026
  5. suryaKommana2662 commented on Sep 4, 2026

    @suryaKommana2662
    Contributor

    @xianjianlf2 Thanks for the detailed report and for confirming that the issue is still reproducible on the latest Flutter stable release (3.47.2). The provided reproduction and testing also confirm that #192286 resolves the issue. Routing this to the team-android for further investigation/review.

  6. added
    platform-androidAndroid applications specifically
    engineflutter/engine related. See also e: labels.
    team-androidOwned by Android platform team
    and removed
    in triagePresently being triaged by the triage team
    on Sep 4, 2026
  7. added
    P2Important issues not at the top of the work list
    triaged-androidTriaged by Android platform team
    P1High-priority issues at the top of the work list
    and removed
    P2Important issues not at the top of the work list
    on Sep 8, 2026
  8. added a commit that references this issue on Nov 3, 2026
    a041edd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority issues at the top of the work listengineflutter/engine related. See also e: labels.platform-androidAndroid applications specificallyteam-androidOwned by Android platform teamtriaged-androidTriaged by Android platform team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions