Xamarin Forms Android版Release模式遇API异常崩溃求助
问题分析与解决方案
核心问题定位
你的Xamarin Forms安卓端出现异常冻结/崩溃,而iOS正常,主要集中在API异常场景,大概率是安卓端全局异常捕获不完整、异步方法调用不当、事件重复注册这几个原因导致的。
具体修复步骤
1. 补全安卓端原生异常捕获
Xamarin Forms的全局异常处理无法覆盖安卓原生层面的未捕获异常,必须在安卓项目的MainActivity中单独处理:
protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); Xamarin.Essentials.Platform.Init(this, savedInstanceState); global::Xamarin.Forms.Forms.Init(this, savedInstanceState); // 捕获安卓原生未处理异常 AndroidEnvironment.UnhandledExceptionRaiser += (sender, e) => { // 用Task.Run避免阻塞UI线程 _ = Task.Run(() => YourExceptionHandlerInstance.HandleExceptionAsync(e.Exception)); e.Handled = true; // 标记为已处理,阻止系统强制崩溃 }; // 捕获未观察到的Task异常 TaskScheduler.UnobservedTaskException += (sender, e) => { _ = Task.Run(() => YourExceptionHandlerInstance.HandleExceptionAsync(e.Exception)); e.SetObserved(); }; // 捕获AppDomain层面的异常 AppDomain.CurrentDomain.UnhandledException += (sender, e) => { if (e.ExceptionObject is Exception exception) { _ = Task.Run(() => YourExceptionHandlerInstance.HandleExceptionAsync(exception)); } }; LoadApplication(new App()); }
2. 修复异常处理器代码缺陷
(1)替换不准确的异常类型判断
把通过GetType().Name判断异常类型的方式,改成更可靠的is关键字,支持继承场景:
// 原代码 // if (exception.GetType().Name == nameof(UnauthorizedException)) // 替换为 if (exception is UnauthorizedException || exception.Message.ToLowerInvariant().Contains("refresh token has expired") || exception.Message.ToLowerInvariant().Contains("invalid refresh token"))
(2)避免重复注册网络事件
HandleNoInternetException中每次触发都注册ConnectivityChanged,会导致事件多次绑定,引发重复执行甚至内存泄漏:
private bool _isConnectivityEventBound = false; private void HandleNoInternetException() { if (Connectivity.NetworkAccess != NetworkAccess.Internet) { // 这里可以添加无网提示逻辑 } if (!_isConnectivityEventBound) { Connectivity.ConnectivityChanged += Connectivity_ConnectivityChanged; _isConnectivityEventBound = true; } } private void Connectivity_ConnectivityChanged(object sender, ConnectivityChangedEventArgs e) { if (e.NetworkAccess == NetworkAccess.Internet) { // 恢复网络后的操作 Connectivity.ConnectivityChanged -= Connectivity_ConnectivityChanged; _isConnectivityEventBound = false; } }
(3)移除空catch块,保留异常日志
空catch会吞掉潜在问题,至少添加日志便于排查:
#if !DEBUG try { //await emailManager.SendFeedbackEmail(exception); } catch (Exception ex) { Log.Error(ex, "发送异常反馈邮件失败"); } #endif
3. 确保异步方法被正确调用
HandleExceptionAsync是异步方法,必须用await调用,避免同步调用导致UI线程死锁:
// 在API调用的catch块中 catch (Exception ex) { await YourExceptionHandlerInstance.HandleExceptionAsync(ex).ConfigureAwait(false); }
调试建议
开启安卓Logcat,查看崩溃时的原生日志,定位是否有未被捕获的JNI异常、主线程阻塞等问题,这是排查安卓端崩溃的关键。
内容的提问来源于stack exchange,提问作者Parvez ali
相关产品推荐
相关产品推荐

