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.98k stars 1.72k forks source link

RegisterForActivityResult does not work #14037

Open dimonovdd opened 1 year ago

dimonovdd commented 1 year ago

Description

RegisterForActivityResult does not work correctly with MauiAppCompatActivity.

I think the issue lies in these two lines:

savedInstanceState?.Remove("android:support:fragments");
savedInstanceState?.Remove("androidx.lifecycle.BundlableSavedStateRegistry.key");

Steps to Reproduce

  1. Clone the repository
  2. Open AndroidApp1.sln
  3. Enable Don't keep activities on Device\Simulator
  4. Add breakpoints in two projects in methods OnActivityResult
  5. Run AndroidApp1
  6. Touch Get result
  7. Choose a contact
  8. Run MauiApp1
  9. Touch Get result
  10. Choose a contact

Link to public reproduction project repository

https://github.com/dimonovdd/RegisterForActivityResult.MAUI

Version with bug

8.0 (current)

Last version that worked well

Unknown/Other

Affected platforms

Android

Affected platform versions

Any

Did you find any workaround?

No response

Relevant log output

No response

dimonovdd commented 1 year ago

@PureWeen Hi

Do you have any ideas? These lines have been changed in #1241

ghost commented 1 year 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.

dimonovdd commented 1 year ago

Backlog? @jsuarezruiz Do you understand the seriousness of this problem? Are we following the path of Xamarin.Froms? If an issue is difficult, then you simply do not have the desire to solve it for several years?

@jonathanpeppers Hi, You are strong in Android development. Do you have any ideas? How can we disable fragment restore without disabling restore of other things?

jonathanpeppers commented 1 year ago

@dimonovdd it looks like you are supposed to override:

protected virtual bool AllowFragmentRestore => false;

Did that not work for you?

@PureWeen can maybe share details on why we need:

savedInstanceState?.Remove("android:support:fragments");
savedInstanceState?.Remove("androidx.lifecycle.BundlableSavedStateRegistry.key");
dimonovdd commented 1 year ago

@dimonovdd it looks like you are supposed to override:

I didn't understand the meaning of it https://github.com/dotnet/maui/discussions/14039

jonathanpeppers commented 1 year ago

I think you override it and return true, will prevent savedInstanceState from being modified?

dimonovdd commented 1 year ago

will prevent savedInstanceState from being modified?

Yes, but the app will crash. And there is no documentation of what else needs to be changed.

jonathanpeppers commented 1 year ago

What is the error message?

dimonovdd commented 1 year ago

A screenshot was attached in the discussion. This exception is not only related to ShellItemRenderer. Almost nothing has ctor (IntPtr javaReference, JniHandleOwnership transfer) or empty ctor

dimonovdd commented 1 year ago

MAUI changed the logic of restoring activity after destroy. These two lines disable default restore of fragments and other Views. But it also disables state restore of other things (RegisterForActivityResult and etc.)

savedInstanceState?.Remove("android:support:fragments");
savedInstanceState?.Remove("androidx.lifecycle.BundlableSavedStateRegistry.key");
PureWeen commented 1 year ago

@dimonovdd it looks like you are supposed to override:

protected virtual bool AllowFragmentRestore => false;

Did that not work for you?

@PureWeen can maybe share details on why we need:

savedInstanceState?.Remove("android:support:fragments");
savedInstanceState?.Remove("androidx.lifecycle.BundlableSavedStateRegistry.key");

The top one has been around forever in Forms https://github.com/xamarin/Xamarin.Forms/pull/246

The second one we added when we bumped up AndroidX because it was causing a similar issue indicated by https://github.com/xamarin/Xamarin.Forms/pull/246

https://github.com/xamarin/Xamarin.Forms/pull/14101/files#diff-89f66fc6d9b2094dcce8863bd3db93823b5ca20d2f2ef588b8e6ffff46fcb0b6R226

Do you happen to know which of these lines is breaking RegisterForActivityResult?

We should probably re-evaluate these. They feel like something that's just adding a band-aid to a different problem.

dimonovdd commented 1 year ago

Do you happen to know which of these lines is breaking RegisterForActivityResult?

yep, savedInstanceState?.Remove("androidx.lifecycle.BundlableSavedStateRegistry.key");

PureWeen commented 1 year ago

Do you happen to know which of these lines is breaking RegisterForActivityResult?

yep, savedInstanceState?.Remove("androidx.lifecycle.BundlableSavedStateRegistry.key");

If you set AllowFragmentRestore to true and then just add

savedInstanceState?.Remove("android:support:fragments");

Does that workaround your issue?

dimonovdd commented 1 year ago

Does that workaround your issue?

No, I changed MauiAppCompatActivity code like this and also the exception

image

PureWeen commented 1 year ago

Does that workaround your issue?

No, I changed MauiAppCompatActivity code like this and also the exception

image

Hmm, yea, it looks like that path broke when we updated AndroidX and then needed to add that other line to account for it.

dimonovdd commented 1 year ago

Hmm, yea, it looks like that path broke when we updated AndroidX and then needed to add that other line to account for it.

I think it will be very painful to tear off this patch. But we definitely have to fix it

dimonovdd commented 1 year ago

Is that issue still in backlog? In how many years will we be able to see a solution?

homeyf commented 1 year ago

Verified this issue with Visual Studio Enterprise 17.8.0 Preview 1.0. Can repro on android platform with sample project. https://github.com/dimonovdd/RegisterForActivityResult.MAUI image image

entdark commented 7 months ago

~~The issue in the sample is probably in creating ActivityResultLauncher before base.OnCreate: https://github.com/dimonovdd/RegisterForActivityResult.MAUI/blob/main/MauiApp1/Platforms/Android/MainActivity.cs#L18 Not in MAUI.~~

Seems like it doesn't matter where it's registered. So @dimonovdd is right that removing the lifecycle saved state doesn't let Activity Result Registry restore and apply pending results.

phunkeler commented 1 month ago

I'm having success with this workaround:

public class MainActivity : MauiAppCompatActivity
{
    protected override bool AllowFragmentRestore => true;

    protected override void OnCreate(Bundle? savedInstanceState)
    {
        ...

        savedInstanceState?
            .GetBundle("androidx.lifecycle.BundlableSavedStateRegistry.key")?
            .Remove("android:support:fragments");

        base.OnCreate(savedInstanceState);
    }
}

14037_api33_workaround