MvvmCross 4.4.0适配Android 12(API31)时MvxAndroidBindingContextHelpers.Current()为空
一、API31(Android12)绑定上下文获取失败导致ViewModel为空的问题
核心原因分析
Android12对Context的生命周期管理和传递逻辑做了更严格的限制,旧版MvvmCross(4.x/5.x)的MvxAndroidBindingContextHelpers.Current()依赖的静态上下文持有逻辑,在Android12下无法正确关联当前Activity的绑定上下文,导致LayoutInflater初始化时无法获取有效上下文,进而ViewModel绑定失败。
可行修复方案
手动初始化绑定上下文
在MainActivity的OnCreate方法中,SetContentView之前手动设置绑定上下文,替代静态Helper的自动获取:protected override void OnCreate(Bundle savedInstanceState) { // 手动初始化绑定上下文,关联当前Activity Context var bindingContext = new MvxAndroidBindingContext(this, this); MvxAndroidBindingContextHelpers.Current = bindingContext; base.OnCreate(savedInstanceState); SetContentView(Resource.Layout.Main); }自定义LayoutInflater适配
替换原有的LayoutInflater实现,在Inflate过程中直接从Activity实例获取绑定上下文,而非依赖静态Helper:public class CustomMvxLayoutInflater : LayoutInflater { private readonly IMvxAndroidBindingContext _bindingContext; public CustomMvxLayoutInflater(Context context, IMvxAndroidBindingContext bindingContext) : base(context) { _bindingContext = bindingContext; } protected CustomMvxLayoutInflater(LayoutInflater original, Context newContext, IMvxAndroidBindingContext bindingContext) : base(original, newContext) { _bindingContext = bindingContext; } public override LayoutInflater CloneInContext(Context newContext) { return new CustomMvxLayoutInflater(this, newContext, _bindingContext); } public override View Inflate(int resourceId, ViewGroup root, bool attachToRoot) { // 使用传入的绑定上下文完成视图绑定 return _bindingContext.BindingInflate(resourceId, root, attachToRoot); } }在Activity中初始化时传入当前绑定上下文:
protected override LayoutInflater OnCreateLayoutInflater() { return new CustomMvxLayoutInflater(base.OnCreateLayoutInflater(), this, this.BindingContext); }检查Activity启动模式与权限
Android12对singleInstance/singleTask等特殊启动模式的Context传递有严格限制,若MainActivity使用此类启动模式,尝试改为standard或singleTop,并确保应用已申请必要的权限(部分权限缺失可能间接导致Context异常)。
二、MvvmCross.Droid.Shared迁移指南
MvvmCross 5.x版本后,MvvmCross.Droid.Shared被拆分至AndroidX兼容的支持包中,迁移步骤如下:
替换NuGet包
- 移除
MvvmCross.Droid.Shared包 - 根据原项目依赖的组件,安装对应支持包:
- 基础Activity/绑定:
MvvmCross.Droid.Support.Core.UI - AppCompat组件兼容:
MvvmCross.Droid.Support.V7.AppCompat - 偏好设置:
MvvmCross.Droid.Support.Preferences
- 基础Activity/绑定:
- 移除
命名空间与类替换
旧类(MvvmCross.Droid.Shared) 新类(对应支持包) MvxSharedCompatActivityMvxAppCompatActivity(来自MvvmCross.Droid.Support.V7.AppCompat)MvxSharedPreferencesMvxPreferences(来自MvvmCross.Droid.Support.Preferences)MvxSharedViewPagerAdapterMvxViewPagerAdapter(来自MvvmCross.Droid.Support.Core.UI)AndroidX迁移适配
API31要求使用AndroidX库,需同步将原项目中的Android Support库替换为AndroidX对应库:- 将
Android.Support.v7.App.AppCompatActivity替换为AndroidX.AppCompat.App.AppCompatActivity - 其他Support组件(如RecyclerView、ViewPager)对应替换为AndroidX版本
- 将
绑定逻辑调整
旧版Shared中的绑定表达式无需大幅修改,但需确保布局文件中使用的命名空间为新版MvvmCross绑定命名空间:xmlns:mvvm="http://schemas.android.com/apk/res-auto"
内容的提问来源于stack exchange,提问作者Acco

