Xamarin Android应用恢复网络时出现“Network is unreachable”错误如何解决?
问题根因
- Xamarin.Android 默认使用的托管
HttpClientHandler会持久化缓存网络路由、DNS 解析结果,当你从无互联网的 AP 切到正常网络后,旧缓存不会自动失效,请求依然走之前的无效网络链路。 - 你用到的
IHttpClientFactory默认会复用HttpMessageHandler实例(默认生命周期 2 分钟),哪怕你重新创建HttpClient,底层绑定的还是旧的 handler,之前的无效网络配置依然生效,所以更换客户端实例无法解决问题。 - 静态
WebRepository的构造函数仅在应用启动时执行一次,初始创建的 handler 绑定的是启动时的网络状态,网络切换后没有触发对应的更新逻辑。
解决方案
1. 优先切换为安卓原生 HttpClient 实现
在 Xamarin.Android 项目属性的「Android 选项」→「高级」设置页,将 HttpClient 实现改为 AndroidClientHandler,替换默认的托管实现。原生实现会自动跟随系统网络状态更新,不会出现缓存不失效的问题。
如果需要代码全局配置,可以在 Startup 或者 MainActivity.OnCreate 中添加:
AppDomain.CurrentDomain.SetData("System.Net.Http.HttpClient.HandlerType", typeof(Xamarin.Android.Net.AndroidClientHandler));
2. 调整 IHttpClientFactory 的 Handler 复用逻辑
如果必须使用托管实现,修改 IHttpClientFactory 的注册配置,缩短 handler 的生命周期,避免长时间复用旧的网络配置:
// 注册时将 handler 生命周期设置为 30 秒 services.AddHttpClient() .SetHandlerLifetime(TimeSpan.FromSeconds(30));
3. 增加网络状态监听逻辑
在安卓项目中注册 ConnectivityManager.NetworkCallback 监听网络切换事件,当网络状态变化时主动清空当前的 HttpClient 实例,下次请求时自动使用新创建的实例:
// 网络切换回调中调用重置方法 WebRepository.ResetClient(); // WebRepository 中新增对应重置方法 public static void ResetClient() { _client?.CancelPendingRequests(); _client?.Dispose(); _client = _clientFactory.CreateClient(); }
4. 优化异常处理逻辑
你当前的异常处理中重新创建 HttpClient 后直接抛出异常,没有重试逻辑,可以新增 1~2 次自动重试,直接用新创建的客户端发起请求,无需等待用户下次触发操作:
catch(HttpRequestException e) when(e.InnerException != null && e.InnerException is SocketException && e.Message.Contains("Network is unreachable")) { _client.CancelPendingRequests(); _client.Dispose(); _client = _clientFactory.CreateClient(); // 新增一次自动重试 if (Globals.LoggedUser != null) _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization", $"{Globals.LoggedUser.Token}"); HttpResponseMessage message = await _client.GetAsync(url).ConfigureAwait(false); return await DeserializeResponseMessageAsync<T>(message); }
内容的提问来源于stack exchange,提问作者Marcelo Menezes
相关产品推荐
相关产品推荐

