Xamarin.Forms Prism项目Base ViewModel初始化Refit时崩溃问题求助
问题根因
你采用字段初始化器直接初始化Refit服务的写法会触发闪退,核心原因是类字段初始化器的执行时机早于ViewModel构造函数、Prism导航初始化以及平台基础配置完成的时机。如果此时HttpUrl.BaseUrl未完成赋值、或者Refit依赖的底层网络栈未就绪,就会抛出未捕获的异常直接闪退。
另外Prism框架本身自带依赖注入容器,不需要你手动在BaseViewModel里初始化服务,通过容器注册的服务天然就是全局可复用的单例,完全符合你的需求。
修复步骤
1. 注册Refit服务到Prism容器
打开项目的App.xaml.cs,在RegisterTypes方法中注册IRestFulService:
protected override void RegisterTypes(IContainerRegistry containerRegistry) { // 确保执行到这里时 HttpUrl.BaseUrl 已经完成赋值 containerRegistry.RegisterSingleton(_ => RestService.For<IRestFulService>(HttpUrl.BaseUrl)); // 你原有其他页面、服务的注册逻辑保持不变 }
如果需要配置全局请求头、超时、拦截器等规则,建议先构造HttpClient实例再传给Refit:
protected override void RegisterTypes(IContainerRegistry containerRegistry) { var httpClient = new HttpClient(new NativeMessageHandler()) { BaseAddress = new Uri(HttpUrl.BaseUrl), Timeout = TimeSpan.FromSeconds(15) }; // 示例:添加全局请求头 httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); containerRegistry.RegisterSingleton(_ => RestService.For<IRestFulService>(httpClient)); }
2. 改造BaseViewModel通过构造注入获取服务
删掉你原来的字段初始化代码,改成构造函数注入:
public class BaseViewModel : BindableBase { protected readonly IRestFulService _restFulService; public BaseViewModel(IRestFulService restFulService) { _restFulService = restFulService; } }
3. 子类ViewModel传递参数给父类
所有继承BaseViewModel的子类,只需要在构造函数中把服务实例传给父类即可:
public class YourPageViewModel : BaseViewModel { public YourPageViewModel(IRestFulService restFulService) : base(restFulService) { // 子类自有初始化逻辑 } }
注意事项
HttpUrl.BaseUrl必须是符合HTTP协议规范的完整地址,比如https://api.xxx.com/,前缀、后缀规则要和你IRestFulService中定义的接口Route匹配。- 如果使用HTTP明文请求,安卓需要配置网络安全配置允许明文访问,iOS需要配置ATS规则放行对应域名,否则网络请求会直接抛出异常。
- 上述注册方式默认是单例模式,所有ViewModel共用同一个
IRestFulService实例,满足你复用的需求。
内容的提问来源于stack exchange,提问作者helper
相关产品推荐
相关产品推荐

