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

Xamarin Prism依赖服务方法无法获取当前上下文变量求助

解决Xamarin Prism中依赖服务无法获取当前上下文变量的问题

我之前也踩过一模一样的坑,你的问题核心在于Android平台的VideoService继承了Activity,但这个类的实例并不是Android系统托管的当前活跃Activity——依赖注入创建的VideoService只是个普通类实例,它的Context(也就是this)要么是空的,要么指向一个无效的Activity对象,自然拿不到当前页面的变量。

下面是具体的修复步骤,一步步来:

1. 重构依赖服务,移除Activity继承

先把VideoService改成普通类,通过构造函数注入当前的Activity上下文,而不是自己继承Activity:

接口保持不变(无需依赖Android组件)

public interface IVideoCommands 
{ 
    void OnToggleVideo(); 
}

重构Android平台实现类

[assembly: Xamarin.Forms.Dependency(typeof(VideoService))]
namespace XTPProto.Droid.Services 
{
    // 去掉Activity继承,改成普通类
    public class VideoService : IVideoCommands 
    {
        private readonly Activity _currentActivity;

        // 通过构造函数注入当前活跃的Activity
        public VideoService(Activity currentActivity)
        {
            _currentActivity = currentActivity ?? throw new ArgumentNullException(nameof(currentActivity));
        }

        public void OnToggleVideo()
        {
            // 现在可以用_currentActivity访问当前上下文的所有变量/控件了
            // 比如:
            // var videoView = _currentActivity.FindViewById<VideoView>(Resource.Id.videoView);
            // videoView.PlayPause();
        }
    }
}

2. 配置Prism依赖注入,注入当前Activity

要让VideoService拿到正确的Activity,需要在Prism的平台初始化器里注册服务时,传入当前活跃的Activity实例。

第一步:配置Xamarin.Essentials跟踪当前Activity

先在Android项目的MainActivity里更新Platform.CurrentActivity,确保它始终指向用户正在交互的页面:

protected override void OnResume()
{
    base.OnResume();
    Platform.CurrentActivity = this;
}

protected override void OnPause()
{
    base.OnPause();
    Platform.CurrentActivity = null;
}

第二步:在Prism平台初始化器中注册服务

创建(或修改)Android项目的IPlatformInitializer实现,注册VideoService和当前Activity:

public class AndroidInitializer : IPlatformInitializer
{
    public void RegisterTypes(IContainerRegistry containerRegistry)
    {
        // 注册当前Activity实例
        containerRegistry.RegisterInstance<Activity>(Platform.CurrentActivity);
        
        // 注册依赖服务,让容器自动注入Activity
        containerRegistry.Register<IVideoCommands, VideoService>();
    }
}

3. 视图模型调用代码无需修改

你的ViewModel调用逻辑保持原样即可,Prism的容器会自动解析出带有正确上下文的IVideoCommands实例:

void OnToogleCommandVid() 
{ 
    _dependencyService.Get<IVideoCommands>().OnToggleVideo(); 
}

为什么原来的方法行不通?

当你让VideoService继承Activity时,这个类的实例是由依赖注入框架创建的,而不是Android系统通过StartActivity等生命周期方法启动的——它没有经过Android的初始化流程,所以this指向的不是当前用户正在操作的页面Activity,自然拿不到当前上下文的变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:50:37