Skip to content

[Android] Fix NRE in ContainerView when Android Context is null during lifecycle transition#34901

Merged
kubaflo merged 3 commits intoinflight/currentfrom
fix/issue-34900-navigation-root-manager-nre
Apr 10, 2026
Merged

[Android] Fix NRE in ContainerView when Android Context is null during lifecycle transition#34901
kubaflo merged 3 commits intoinflight/currentfrom
fix/issue-34900-navigation-root-manager-nre

Conversation

@rmarinho
Copy link
Copy Markdown
Member

@rmarinho rmarinho commented Apr 9, 2026

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 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:

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 and others added 3 commits April 8, 2026 19:58
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>
Copilot AI review requested due to automatic review settings April 9, 2026 17:16
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 9, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 34901

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 34901"

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 InvalidOperationException in ContainerView’s constructor when context.Context is null, replacing a deeper/opaque NRE.
  • Provide a clear, actionable error message describing the likely lifecycle-related cause.

@kubaflo kubaflo changed the base branch from main to inflight/current April 10, 2026 17:36
@kubaflo kubaflo merged commit 08fae29 into inflight/current Apr 10, 2026
7 of 16 checks passed
@kubaflo kubaflo deleted the fix/issue-34900-navigation-root-manager-nre branch April 10, 2026 17:37
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
```

---------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Android] NullReferenceException in NavigationRootManager.Connect when mapping Window content

5 participants