Skip to content

[Bug]: WireUpControls throws exception in net8.0-android #3714

@tommy10344

Description

@tommy10344

Describe the bug 🐞

When calling ReactiveUI.ControlFetcherMixin.WireUpControls() in a .NET 8 Android app (net8.0-android), even though the correct resource ID is specified, a MissingFieldException is thrown.

Stacktrace:

Exception has occurred: System.MissingFieldException
Failed to wire up the Property XXX to a View in your layout with a corresponding identifier
    at ReactiveUI.ControlFetcherMixin.WireUpControls(Activity activity, ResolveStrategy resolveMembers) in /_/src/ReactiveUI/Platforms/android/ControlFetcherMixin.cs:166
    at ReactiveUI_WireUpControls_Issue.MainActivity.OnCreate(Bundle savedInstanceState) in /path/to/projects/ReactiveUI-WireUpControls-Issue/MainActivity.cs:19
    at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_(IntPtr jnienv, IntPtr native__this, IntPtr native_savedInstanceState) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net8.0/android-34/mcw/Android.App.Activity.cs:3082
    at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PPL_V(_JniMarshal_PPL_V callback, IntPtr jnienv, IntPtr klazz, IntPtr p0) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:125

Step to reproduce

  1. Install .NET 8. (I installed 8.0.100)
  2. Create a new net8.0-android project using dotnet new android command.
  3. Add reference to ReactiveUI version 19.5.39
  4. Open MainActivity.cs and change it so that MainActivity inherits ReactiveUI.ReactiveActivity.
public class MainActivity : ReactiveActivity
  1. Assign an ID(android:id) to the TextView in activity_main.xml and add a member to MainActivity.cs to wire it up.
    <TextView 
        android:id="@+id/app_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="@string/app_text"
    />
    [WireUpResource("app_text")]
    public TextView AppText { get; private set; }
  1. Add a call to WireUpControls() after SetContentView() in OnCreate().
this.WireUpControls(ControlFetcherMixin.ResolveStrategy.ExplicitOptIn);
  1. Build and launch application.
  2. MissingFieldException is thrown from WireUpControls().

Reproduction repository

https://github.com/tommy10344/ReactiveUI-WireUpControls-Issue

Expected behavior

After launching the application, the TextView should be wired up correctly, and the initial screen should be displayed.

Build the same code with .NET 7 (net7.0-android), it works as expected. (Confirmed in the dotnet7 branch of the reproduction repository)

Screenshots 🖼️

MissingFieldException

IDE

Visual Studio Code

Operating system

Android

Version

13

Device

Emulator

ReactiveUI Version

19.5.39

Additional information ℹ️

.NET 8 seems to have changed access to Android resources, is this issue related to this?
https://devblogs.microsoft.com/dotnet/android-resource-designer-dotnet-8/

Reading the implementation of WireUpControls(), it looks like it uses reflection to reference the Resource.Id class in the assembly of the application itself.
https://github.com/reactiveui/ReactiveUI/blob/main/src/ReactiveUI/Platforms/android/ControlFetcherMixin.cs#L230

However, in .NET8, it seems that a new assembly called _Microsoft.Android.Resource.Designer is created and the Resource.Id class is generated there.
I am guessing that this may be related to the problem.
(I'm not very familiar with .NET, so sorry if I'm wrong)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions