Xamarin Forms部署至Android设备后加载数据卡顿无响应问题
问题原因及解决方法
1. 禁止在ViewModel构造函数中执行异步网络请求
构造函数为同步执行逻辑,你当前使用Task.Run的fire-and-forget写法在Xamarin.Android启动阶段会存在上下文缺失问题:应用启动时主线程正忙于渲染视图、初始化核心资源,异步请求完成后的回调无法被正确调度到主线程更新绑定属性,就会出现服务端已收到请求、但客户端无返回的现象。
正确做法是绑定MVVM框架的页面生命周期事件,等待页面完全挂载到视图树后(例如对应ViewModel的OnAppearing/InitializeAsync生命周期钩子)再发起数据请求。
2. 补充HTTP请求的上下文配置
你当前的异步请求没有配置ConfigureAwait,默认会捕获主线程上下文,连续两次await操作(GetAsync、ReadAsStringAsync)会和启动阶段的主线程任务抢占调度资源,很容易出现调度延迟甚至死锁。修改GetFromServer方法,非UI相关的异步操作都配置ConfigureAwait(false)跳过上下文捕获,更新绑定属性时再主动切回主线程:
// 修正后的请求方法 public async Task<T> GetFromServer<T>(string url) { // 注意你原代码中的_httpClientFactpry为拼写错误,实际运行请修正为HttpClientFactory的正确变量名 HttpClient httpClient = _httpClientFactory.CreateClient("myClientName"); HttpResponseMessage response = await httpClient.GetAsync(url).ConfigureAwait(false); string responseJson = await response.Content.ReadAsStringAsync().ConfigureAwait(false); return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(responseJson); } // 修正后的请求调用逻辑 Task.Run(async () => { try { var result = await GetFromServer<SomeObjectType>("some URL"); // 使用Xamarin.Essentials的MainThread主动切回主线程更新绑定属性 Xamarin.Essentials.MainThread.BeginInvokeOnMainThread(() => { MyDataBoundObject = result; }); } catch (Exception ex) { // 补充异常捕获逻辑,避免请求出错无感知 Android.Util.Log.Debug("ApiRequestError", ex.ToString()); } });
3. 启动阶段增加网络状态校验
Android 10及以上系统中,应用刚启动时网络权限校验、ConnectivityManager的网络状态初始化还未完成,此时发起的请求会被系统暂存,不会立刻返回结果。这也对应你提到的「页面加载完成后按钮点击触发请求正常」的现象,此时应用已完成启动流程,网络状态已经就绪。
可以在启动请求前先调用Xamarin.Essentials的Connectivity API检查网络状态,确认网络可用后再发起请求。
内容的提问来源于stack exchange,提问作者Travis Pettry
相关产品推荐
相关产品推荐

