Our Xamarin Android app relies heavily on some older components in MvvmCross 4.4.0 and so has not been updated to modern versions.
We used the guide found here to modernise just enough to get over the API 29/Android 10 hurdle: https://blog.ostebaronen.dk/2020/08/old-mvvmcross-and-android-10.html
We're now at the API 31/Android 12 hurdle and, whilst everything builds and executes fine with API 31 when running on Android 11 and below, Android 12 is crashing.
The MainActivity is initialising with a null ViewModel because the LayoutInflater (already corrected for API 29) cannot retrieve the current binding context with MvxAndroidBindingContextHelpers.Current().
Nothing in the Android 12 behaviour changes guides gives an indication as to what is causing this change. We have also reviewed changes in modern versions of the MvvmCross.Binding source and can't see any obvious changes that correct this behaviour.
This is the code in LayoutInflater.cs where the problem first surfaces:
public override View? Inflate(int resource, ViewGroup? root, bool attachToRoot)
{
// Make sure our private factory is set since LayoutInflater > Honeycomb
// uses a private factory.
SetPrivateFactoryInternal();
// Save the old factory in case we are recursing because of an MvxAdapter etc.
IMvxLayoutInflaterHolderFactory? originalFactory = _bindingVisitor.Factory;
try
{
IMvxLayoutInflaterHolderFactory? factory = null;
// Get the current binding context
var currentBindingContext = MvxAndroidBindingContextHelpers.Current();
// currentBindingContext is null on Android 12, not on Android 11 and below
if (currentBindingContext != null)
{
factory = FactoryFactory?.Create(currentBindingContext.DataContext);
// Set the current factory used to generate bindings
if (factory != null)
_bindingVisitor.Factory = factory;
}
// Inflate the resource
var view = base.Inflate(resource, root, attachToRoot);
// Register bindings with clear key
if (currentBindingContext != null)
{
if (factory != null)
currentBindingContext.RegisterBindingsWithClearKey(view, factory.CreatedBindings);
}
return view;
}
finally
{
_bindingVisitor.Factory = originalFactory;
}
}
Any insight as to potential causes of the problem would be welcome, even if it's a concrete reason why MvvmCross 4.4.0 is simply no-longer viable on Android 12.
Thanks very much.
Update: We have now successfully updated to MvvmCross 5.0.1 and the problem still remains (which we expected). Our dependency is on MvvmCross.Droid.Shared, which is removed from newer versions. Can anybody recommend a guide on migrating away from MvvmCross.Droid.Shared please, as it doesn't appear to be mentioned in the upgrade guides other than to just remove it?
Update 2: Switching out the LayoutInflater for the one from MvvmCross 9.0.1 makes no difference. We've done this simply to rule that out. The issue feels like it related more to Binding.
The issue was not directly related to MvvmCross, but rather a change in Android 12 behaviour that prevented initialisation in a manner that meant ViewModel binding wasn't happening despite the rest of the code executing.
The resolution was to add some specific AndroidX initialisation lines to the AndroidManifest:
<provider android:name="androidx.startup.InitializationProvider" android:authorities="${applicationId}.androidx-startup">
<meta-data android:name="androidx.lifecycle.ProcessLifecycleInitializer" android:value="androidx.startup" />
</provider>
...and to