You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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绑定失败。

可行修复方案

  1. 手动初始化绑定上下文
    在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);
    }
    
  2. 自定义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);
    }
    
  3. 检查Activity启动模式与权限
    Android12对singleInstance/singleTask等特殊启动模式的Context传递有严格限制,若MainActivity使用此类启动模式,尝试改为standard或singleTop,并确保应用已申请必要的权限(部分权限缺失可能间接导致Context异常)。

二、MvvmCross.Droid.Shared迁移指南

MvvmCross 5.x版本后,MvvmCross.Droid.Shared被拆分至AndroidX兼容的支持包中,迁移步骤如下:

  1. 替换NuGet包

    • 移除MvvmCross.Droid.Shared包
    • 根据原项目依赖的组件,安装对应支持包:
      • 基础Activity/绑定:MvvmCross.Droid.Support.Core.UI
      • AppCompat组件兼容:MvvmCross.Droid.Support.V7.AppCompat
      • 偏好设置:MvvmCross.Droid.Support.Preferences
  2. 命名空间与类替换

    旧类(MvvmCross.Droid.Shared)新类(对应支持包)
    MvxSharedCompatActivityMvxAppCompatActivity(来自MvvmCross.Droid.Support.V7.AppCompat)
    MvxSharedPreferencesMvxPreferences(来自MvvmCross.Droid.Support.Preferences)
    MvxSharedViewPagerAdapterMvxViewPagerAdapter(来自MvvmCross.Droid.Support.Core.UI)
  3. AndroidX迁移适配
    API31要求使用AndroidX库,需同步将原项目中的Android Support库替换为AndroidX对应库:

    • 将Android.Support.v7.App.AppCompatActivity替换为AndroidX.AppCompat.App.AppCompatActivity
    • 其他Support组件(如RecyclerView、ViewPager)对应替换为AndroidX版本
  4. 绑定逻辑调整
    旧版Shared中的绑定表达式无需大幅修改,但需确保布局文件中使用的命名空间为新版MvvmCross绑定命名空间:xmlns:mvvm="http://schemas.android.com/apk/res-auto"

内容的提问来源于stack exchange,提问作者Acco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 21:55:21