Search code examples
xamarinxamarin.formsxamarin.androidmvvmcross

Xamarin Forms + MvvmCross Platform Renderers Issue


I'm in the process of updating an application from Xamarin Forms 2.4 to 3.2 and integrating MvvmCross 6.2 into a Xamarin Forms application.

The update to Forms 3.2 went without a hitch, the updated app ran fine. But I've stumbled during the MvvmCross integration.

When attempting to Debug the application it gets to a break-point in my code on this line:

return NavigationService.Navigate<LoginViewModel>();

MvvmCross seems happy as I get to step into the LoginViewModel code. However, when it attempts to render the screen the app bombs with the following exception.

Exception - Highlights

NullReferenceException
Xamarin.Forms.Platform.Android.IPlatformLayout.OnLayout(...)
Xamarin.Forms.Platform.Android\AppCompat\Platform.cs:214

Looking at line 214 here shows:

Android.Platform.GetRenderer(Page).UpdateLayout();

First thing I did was checked over all the code in my custom renderers and all looks fine.

Then I removed all instances of my custom renderers from the LoginView Xaml but the problem persists. Which led me to thinking it is something in the configuration I'm missing.

In my Android setup class I have this code:

protected override IMvxAndroidViewPresenter CreateViewPresenter()
{
    return new MvxAppCompatViewPresenter(AndroidViewAssemblies);
}

I've compared my setup code to this example and it all seems to align. I've no idea where to look next.

Any ideas on things to check or a known solution would be appreciated. I've not managed to configure things so i can step through the Xamarin.Forms code as it so getting a handle on what is null is proving awkward.

Exception - More info

 UNHANDLED EXCEPTION:
 System.NullReferenceException: Object reference not set to an instance of an object.
   at Xamarin.Forms.Platform.Android.AppCompat.Platform.Xamarin.Forms.Platform.Android.IPlatformLayout.OnLayout (System.Boolean changed, System.Int32 l, System.Int32 t, System.Int32 r, System.Int32 b) [0x00017] in D:\a\1\s\Xamarin.Forms.Platform.Android\AppCompat\Platform.cs:214
   at Xamarin.Forms.Platform.Android.PlatformRenderer.OnLayout (System.Boolean changed, System.Int32 l, System.Int32 t, System.Int32 r, System.Int32 b) [0x0000e] in D:\a\1\s\Xamarin.Forms.Platform.Android\PlatformRenderer.cs:73 
   at Android.Views.ViewGroup.n_OnLayout_ZIIII (System.IntPtr jnienv, System.IntPtr native__this, System.Boolean changed, System.Int32 l, System.Int32 t, System.Int32 r, System.Int32 b) [0x00009] in <b72bf8f25b8d497a89864a71b1ed8899>:0 
   at (wrapper dynamic-method) System.Object.40(intptr,intptr,bool,int,int,int,int)
JNI RegisterNativeMethods: attempt to register 0 native methods for android.runtime.JavaProxyThrowable

Solution

  • For anyone else finding this in the future ...

    All the reading I did around this suggests that this exception is essentially misleading. Of all the solutions I read online each one was different meaning there are a whole stack of root causes that end up with the same error.

    In my case, during the migration of code I'd neglected to remove an old line of code in my MainActivity.cs:

    LoadApplication(new App())
    

    This was a required boot-strapping method in the apps previous incarnation. After having introduced such a vastly different boot-strap process calling this method interferes with the new initialisation code.

    The method is still valid as it wasn't marked as obsolete, so never got flagged as problematic by the compiler.