dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
21.99k stars 1.72k forks source link

Changing MainPage of a Maui app breaks OnBackPressedDispatcher callback #19203

Open mikeluken opened 9 months ago

mikeluken commented 9 months ago

Description

I have upgraded my Maui app to use .net8 and target Android 14. In doing so, I am trying to eliminate the deprecated base.OnBackPressed(); but there appears to be a bug.

Old logic:

// MainActivity.cs
public override void OnBackPressed()
{
    if (someCondition() == true)
    {
        HandleBackPressMyself();
    }
    else
    {
        base.OnBackPressed();
    }
}

I am launching my page like this:

// App.xaml.cs
public App()
{
    InitializeComponent();
    Start();
}

private async void Start()
{
    var page = serviceProvider.GetRequiredService<MyFirstPage>();
    Application.Current?.Dispatcher.Dispatch(async () =>
    {
        ((App)Application.Current).MainPage = page;
        await Task.Delay(1);
    };
}

That is pretty straightforward and has always worked. Now, I am trying to use the OnBackPressedDispatcher like this:

// MainActivity.cs
protected override void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);
    OnBackPressedDispatcher.AddCallback(this, new BackPressedCallback(this));
}
// BackPressedCallback.cs
public class BackPressedCallback : OnBackPressedCallback
{
    private readonly Activity activity;

    public BackPressedCallback(Activity activity) : base(true)
    {
        this.activity = activity;
    }

    public override void HandleOnBackPressed()
    {
        if (someCondition() == true)
        {
            HandleBackPressMyself();
        }
        else
        {
            var mainPage = ((App)Microsoft.Maui.Controls.Application.Current)?.MainPage;
            mainPage.SendBackButtonPressed();
        }
    }
}

This all works well as long as I push new pages to the stack using await navigationPage.PushAsync(newPage);.

However, there are a couple of scenarios where I want to remove the MainPage and replace it with an altogether new page like so:

((App)Application.Current).MainPage = loginPage;

As soon as I do this, the HandleOnBackPressed() in the BackPressedCallback stops firing, and all my back navigation stops working entirely.

Thanks!

Steps to Reproduce

I have added a github demo of the issue here that can be downloaded and played with (see link)

1 - Launch the app on Android

2 - Test the navigation: Page 1 -> Page 2 -> Page 3. Once on page three, press the physical back button on Android and navigate back to page 1. So far, all is working.

3 - Expand the Drawer menu on the left. Click on the LOGOUT button. This will just take you back to page 1, but will do so by re-setting MainPage.

4 - Navigate to page 3.

5 - Try to use the physical back button again. The back navigation no longer works.

Link to public reproduction project repository

https://github.com/mikeluken/MauiSample

Version with bug

8.0.3

Is this a regression from previous behavior?

Not sure, did not test other versions

Last version that worked well

Unknown/Other

Affected platforms

Android

Affected platform versions

No response

Did you find any workaround?

No

Relevant log output

No response

PureWeen commented 9 months ago

@mikeluken can you test the latest nightly and see if that resolves this issue for you?

https://github.com/dotnet/maui/wiki/Nightly-Builds

ghost commented 9 months ago

Hi @mikeluken. We have added the "s/needs-info" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

mikeluken commented 9 months ago

I just tried this with the latest nightly build (8.0.4-nightly.9714) and it does not appear to fix the issue.

I updated the following:

Microsoft.Maui.Controls Microsoft.Maui.Controls.Compatibility

Is there something else I was supposed to update?

ghost commented 9 months ago

We've added this issue to our backlog, and we will work to address it as time and resources allow. If you have any additional information or questions about this issue, please leave a comment. For additional info about issue management, please read our Triage Process.

mr5z commented 8 months ago

I was having the same issue until I added this into AndroidManifest.xml

<application
  ...
  android:enableOnBackInvokedCallback="true"
</application>
mikeluken commented 8 months ago

I was having the same issue until I added this into AndroidManifest.xml

<application
  ...
  android:enableOnBackInvokedCallback="true"
</application>

I already have that included and am still having the same issue.

mikeluken commented 8 months ago

Is there any update on this? I tried with the latest nightly build (8.0.6-nightly.9831) and this still hasn't been fixed... Thanks...

PureWeen commented 6 months ago

@mikeluken can you try the latest nightly build again? there are some changes that are part of the next release that might resolve this

jfversluis commented 1 month ago

Also please note that MainPage will become deprecated as of .NET 9