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.94k stars 1.7k forks source link

WebView crashes Maui every time the app resumes in Android with R8 enabled (Need R8 for optimization, obfuscation, and code shrinking) #23027

Closed jonmdev closed 3 weeks ago

jonmdev commented 2 months ago

Description

The benefits of R8 are discussed by Google in terms of code shrinking, optimization, and obfuscation here: https://developer.android.com/build/shrink-code

Maui supports R8, but when it is enabled in a project featuring WebView, the app will crash in Android every time it resumes from being stopped in the background.

This was previously described here and more info is at those reports:

I previously believed this was a MauiHybridWebView issue. However, I have tested further and it is not. It is actually a WebView issue. MauiHybridWebView simply inherits from WebView so obviously shows the same behavior. But it is fundamentally a WebView problem, and must be fixed in WebView.

Bug Description

Apps featuring WebView (or MauiHybridWebView) always run perfectly on the first app start (whether R8 is enabled or disabled).

However, if Android stops the app in the background (ie. OnStop() occurs) and restarts the app in the background, the app then always crashes when R8 is enabled. When R8 is disabled, it restarts smoothly.

How to Trigger Android App Restart

To make Android stop and restart the app and demonstrate this:

Using this method, every time, when the app is built with R8 in Release mode and Android tries to restart it, it crashes.

Repro Bug Projects

To illustrate, the WebView Bug Project is just a default Maui app with WebView added. App.xaml.cs is only changed to:

namespace WebViewR8Bug {
    public partial class App : Application {
        public App() {

            ContentPage mainPage = new();
            this.MainPage = mainPage;

            AbsoluteLayout absRoot = new();
            mainPage.Content = absRoot;

            WebView webView = new();
            webView.WidthRequest = 300; 
            webView.HeightRequest = 300;
            webView.Source = "https://google.com";

            absRoot.Add(webView);
        }
    }
}

No other changes are made.

Steps To Reproduce

1) Open Developer Options in Android Phone and set Background Process Limit to 0-1 range. 2) Build Bug Project in Release to Android device with R8 Enabled (as it is by default). 3) Press ||| button on Android bottom tray and navigate to a few other open apps sequentially (this will trigger Android to run onStop() and stop the Maui App process in the background). 4) Press ||| button on Android bottom tray and navigate back to the Maui App. 5) With R8 enabled, it will always then briefly show the splash icon and crash. 6) If you repeat the above steps with R8 disabled, no crash occurs - it will instead restart the app smoothly as expected.

I also note the plain default Maui app (without WebView) does not crash with R8 enabled or disabled. It only crashes with R8 enabled once WebView has been added. Thus this is specifically provoked by the addition of WebView.

Any help or outlook on a fix would be very, very appreciated.

Version with bug

8.0.40 SR5

Is this a regression from previous behavior?

No, this is something new

Last version that worked well

Unknown/Other

Affected platforms

Android

github-actions[bot] commented 2 months ago

Hi I'm an AI powered bot that finds similar issues based off the issue title.

Please view the issues below to see if they solve your problem, and if the issue describes your problem please consider closing this one and thumbs upping the other issue to help us prioritize it. Thank you!

Closed similar issues:

Note: You can give me feedback by thumbs upping or thumbs downing this comment.

jonmdev commented 1 month ago

As discussed here: https://github.com/dotnet/android/issues/2804

This issue is related to a CREATOR method being stripped by R8.

This can be solved by the following.

Add a Platforms/Android/proguard.cfg file that says:

-keepnames class * implements android.os.Parcelable {
    public static final ** CREATOR;
}

Mark the file properties as ProGuardConfiguration as shown here: https://learn.microsoft.com/en-us/previous-versions/xamarin/android/deploy-test/release-prep/proguard?tabs=windows

Keep in mind due to this bug you may need to adjust the csproj to get the option for this (ProguardConfiguration option is only visible if android is your first entry in the TargetFrameworks of the csproj): https://github.com/dotnet/maui/issues/23523

After this the crash no longer occurs.

Here is a similar thread where similar issues are discussed: https://github.com/dotnet/maui/issues/13413

I think that will need to be added as a Maui fix.

jfversluis commented 3 weeks ago

Until we decide that R8 will be enabled by default, I don't think we will be adding anything to MAUI by default. This might be something for a doc (@davidbritch) or else we'll have this issue for people to find now.

Thanks!