[Android] Fix NRE in ContainerView when Android Context is null during lifecycle transition#34901
Merged
kubaflo merged 3 commits intoinflight/currentfrom Apr 10, 2026
Conversation
Backport of #34801 to main. The official pack pipeline doesn't need iOS simulators — it only builds and packs NuGet packages. The simulator install step is timing out on macOS agents, blocking BAR build production. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Description Implements the `x:Code` XAML directive, allowing inline C# method definitions directly in XAML files. This complements the existing XEXPR (C# Expressions) feature. Fixes #34712 ## What it does `x:Code` lets you define methods inline in XAML: ```xml <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="MyApp.MainPage"> <x:Code><![CDATA[ void OnButtonClicked(object sender, EventArgs e) { // inline C# method } ]]></x:Code> <Button Clicked="OnButtonClicked" Text="Click me" /> </ContentPage> ``` ## Constraints - **Requires XSG (XAML Source Generator)** — not supported by Runtime inflation or XamlC - **Requires `EnablePreviewFeatures`** — same gate as XEXPR - **Must be a direct child of the root element** (WPF parity) - **Must use CDATA** for the code block content - **Must have `x:Class`** on the root element ## Architecture x:Code is implemented as a **third source generator pipeline** alongside CodeBehind (CB) and InitializeComponent (IC): ``` CB → x:Code → IC ``` - `ComputeXCodeSource()` extracts code blocks from parsed XAML - `XCodeCodeWriter` emits a bare partial class (namespace + class + verbatim code, no usings) - The emitted syntax trees feed into the compilation before IC runs - All IC visitors skip x:Code elements via `GeneratorHelpers.IsXCodeElement()` Output hint name format: `{path}_{FileName}.xaml.xcode.cs` ## Diagnostics | ID | Condition | |----|-----------| | MAUIX2012 | `EnablePreviewFeatures` not set (reused from XEXPR) | | MAUIX2015 | x:Code not a direct child of root element | | MAUIX2016 | x:Code used without `x:Class` | ## Tests - **6 SourceGen unit tests** — happy path, multiple blocks, no CDATA, diagnostics, no-op - **4 Xaml.UnitTests** — SourceGen success, Runtime failure, XamlC failure, MockSourceGenerator no-diagnostics --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace opaque NullReferenceException with an informative InvalidOperationException when the Android Context (stored via WeakReference to the Activity) has been collected during a lifecycle transition. The NRE manifested in NavigationRootManager.Connect when calling view.ToContainerView(mauiContext), which creates a ContainerView whose base LinearLayout constructor received a null Context. Fixes #34900 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 34901Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 34901" |
Contributor
There was a problem hiding this comment.
Pull request overview
Improves Android crash diagnostics in ContainerView by throwing an informative exception when IMauiContext.Context is unavailable during lifecycle transitions, addressing the NRE reported in #34900.
Changes:
- Add an explicit
InvalidOperationExceptioninContainerView’s constructor whencontext.Contextis null, replacing a deeper/opaque NRE. - Provide a clear, actionable error message describing the likely lifecycle-related cause.
kubaflo
approved these changes
Apr 10, 2026
3 tasks
PureWeen
pushed a commit
that referenced
this pull request
Apr 14, 2026
…g lifecycle transition (#34901) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Description Fixes #34900 Replaces an opaque `NullReferenceException` with an informative `InvalidOperationException` in `ContainerView` when the Android `Context` is no longer available. ### Root Cause `IMauiContext.Context` (the Android `Context`) is stored via a `WeakReference` to the Activity. During lifecycle transitions (e.g., Activity being GC'd), this reference can become null. When `NavigationRootManager.Connect()` calls `view.ToContainerView(mauiContext)`, it creates a `ContainerView` whose base `LinearLayout` constructor receives a null `Context`, causing an NRE deep in the JNI interop layer. ### Fix Added a null-coalescing throw expression in the `ContainerView` constructor: ```csharp public ContainerView(IMauiContext context) : base(context.Context ?? throw new InvalidOperationException( "Unable to create a ContainerView: the Android Context is no longer available. " + "This can occur when the Activity has been collected during a lifecycle transition.")) ``` This provides a clear, actionable error message instead of the cryptic NRE that pointed at `NavigationRootManager.Connect` line 60. ### Stack trace from the original crash ``` [AndroidRuntime] at Microsoft.Maui.Platform.NavigationRootManager.Connect [AndroidRuntime] at Microsoft.Maui.Handlers.WindowHandler.CreateRootViewFromContent [AndroidRuntime] at Microsoft.Maui.Handlers.WindowHandler.MapContent ``` ---------
devanathan-vaithiyanathan
pushed a commit
to Tamilarasan-Paranthaman/maui
that referenced
this pull request
Apr 21, 2026
…g lifecycle transition (dotnet#34901) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Description Fixes dotnet#34900 Replaces an opaque `NullReferenceException` with an informative `InvalidOperationException` in `ContainerView` when the Android `Context` is no longer available. ### Root Cause `IMauiContext.Context` (the Android `Context`) is stored via a `WeakReference` to the Activity. During lifecycle transitions (e.g., Activity being GC'd), this reference can become null. When `NavigationRootManager.Connect()` calls `view.ToContainerView(mauiContext)`, it creates a `ContainerView` whose base `LinearLayout` constructor receives a null `Context`, causing an NRE deep in the JNI interop layer. ### Fix Added a null-coalescing throw expression in the `ContainerView` constructor: ```csharp public ContainerView(IMauiContext context) : base(context.Context ?? throw new InvalidOperationException( "Unable to create a ContainerView: the Android Context is no longer available. " + "This can occur when the Activity has been collected during a lifecycle transition.")) ``` This provides a clear, actionable error message instead of the cryptic NRE that pointed at `NavigationRootManager.Connect` line 60. ### Stack trace from the original crash ``` [AndroidRuntime] at Microsoft.Maui.Platform.NavigationRootManager.Connect [AndroidRuntime] at Microsoft.Maui.Handlers.WindowHandler.CreateRootViewFromContent [AndroidRuntime] at Microsoft.Maui.Handlers.WindowHandler.MapContent ``` ---------
PureWeen
pushed a commit
that referenced
this pull request
Apr 22, 2026
…g lifecycle transition (#34901) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Description Fixes #34900 Replaces an opaque `NullReferenceException` with an informative `InvalidOperationException` in `ContainerView` when the Android `Context` is no longer available. ### Root Cause `IMauiContext.Context` (the Android `Context`) is stored via a `WeakReference` to the Activity. During lifecycle transitions (e.g., Activity being GC'd), this reference can become null. When `NavigationRootManager.Connect()` calls `view.ToContainerView(mauiContext)`, it creates a `ContainerView` whose base `LinearLayout` constructor receives a null `Context`, causing an NRE deep in the JNI interop layer. ### Fix Added a null-coalescing throw expression in the `ContainerView` constructor: ```csharp public ContainerView(IMauiContext context) : base(context.Context ?? throw new InvalidOperationException( "Unable to create a ContainerView: the Android Context is no longer available. " + "This can occur when the Activity has been collected during a lifecycle transition.")) ``` This provides a clear, actionable error message instead of the cryptic NRE that pointed at `NavigationRootManager.Connect` line 60. ### Stack trace from the original crash ``` [AndroidRuntime] at Microsoft.Maui.Platform.NavigationRootManager.Connect [AndroidRuntime] at Microsoft.Maui.Handlers.WindowHandler.CreateRootViewFromContent [AndroidRuntime] at Microsoft.Maui.Handlers.WindowHandler.MapContent ``` ---------
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Description
Fixes #34900
Replaces an opaque
NullReferenceExceptionwith an informativeInvalidOperationExceptioninContainerViewwhen the AndroidContextis no longer available.Root Cause
IMauiContext.Context(the AndroidContext) is stored via aWeakReferenceto the Activity. During lifecycle transitions (e.g., Activity being GC'd), this reference can become null. WhenNavigationRootManager.Connect()callsview.ToContainerView(mauiContext), it creates aContainerViewwhose baseLinearLayoutconstructor receives a nullContext, causing an NRE deep in the JNI interop layer.Fix
Added a null-coalescing throw expression in the
ContainerViewconstructor:This provides a clear, actionable error message instead of the cryptic NRE that pointed at
NavigationRootManager.Connectline 60.Stack trace from the original crash