Xamarin Android:捕获异常时阻止启动新Activity的方案咨询
解决方案:Xamarin Android 异常捕获后控制Activity跳转
这个问题我之前也遇到过——核心原因是你在ExecuteNonQuery里的return只是终止了当前方法的执行,但按钮点击事件里的跳转代码不受影响,依然会继续运行,所以才会出现Alert还没看完页面就跳走的情况。下面给你两个精准匹配需求的解决方案:
方案一:仅当操作成功时跳转Activity
通过让ExecuteNonQuery返回执行状态,外部根据状态决定是否执行跳转逻辑,异常时只弹出Alert不跳转。
步骤1:修改fsp_SellDet_New_ByItemID类的ExecuteNonQuery方法
public bool ExecuteNonQuery(int _SellID, int _ItemID, int _PodID, decimal _ItemSellQty, decimal _ItemPrice, decimal _ItemPricePer, decimal _BaseDiscount, decimal _AdditionalDiscount, decimal _ItemSum, decimal _ItemVAT, string _ItemCode, string _ItemShortName, string _ItemBrand, string _ItemIssue) { try { // 你的数据库操作及业务逻辑代码 // ... return true; // 操作成功返回true } catch (Exception ex) { var _dlgAlert = new AlertDialog.Builder(this).Create(); _dlgAlert.SetMessage(ex.Message); _dlgAlert.SetTitle(Resources.GetString(Resource.String.Error)); _dlgAlert.SetButton("OK", delegate { _dlgAlert.Dismiss(); }); _dlgAlert.Show(); return false; // 异常返回false } }
步骤2:修改按钮点击事件的逻辑
fsp_SellDet_New_ByItemID fsp_SellDet_New_ByItemID = new fsp_SellDet_New_ByItemID(this); bool operationSuccess = fsp_SellDet_New_ByItemID.ExecuteNonQuery(_SellID, _ItemID, _PodID, _ItemSellQty, _ItemPrice, _ItemPricePer, -_BaseDiscount, -_AdditionalDiscount, _ItemSum, _ItemVAT, _ItemCode, _ItemShortName, _ItemBrand, _ItemIssue); // 仅当操作成功时,才执行跳转 if (operationSuccess) { Intent i = new Intent(this, typeof(SellDet)); StartActivity(i); Finish(); }
这个方案的好处是逻辑清晰,用户能第一时间看到错误信息,不会被页面跳转打断。
方案二:点击Alert的OK按钮后再跳转Activity
如果需要用户确认错误信息后再执行跳转,可以通过委托回调的方式,把跳转逻辑传递到ExecuteNonQuery方法中,在Alert的按钮点击事件里触发跳转。
步骤1:修改fsp_SellDet_New_ByItemID类
public class fsp_SellDet_New_ByItemID { private readonly Context _context; private readonly Action _onComplete; // 定义完成后的回调(跳转逻辑) // 构造函数新增回调参数 public fsp_SellDet_New_ByItemID(Context context, Action onComplete) { _context = context; _onComplete = onComplete; } public void ExecuteNonQuery(int _SellID, int _ItemID, int _PodID, decimal _ItemSellQty, decimal _ItemPrice, decimal _ItemPricePer, decimal _BaseDiscount, decimal _AdditionalDiscount, decimal _ItemSum, decimal _ItemVAT, string _ItemCode, string _ItemShortName, string _ItemBrand, string _ItemIssue) { try { // 你的数据库操作及业务逻辑代码 // ... _onComplete?.Invoke(); // 成功后直接触发跳转 } catch (Exception ex) { var _dlgAlert = new AlertDialog.Builder(_context).Create(); _dlgAlert.SetMessage(ex.Message); _dlgAlert.SetTitle(_context.Resources.GetString(Resource.String.Error)); // 点击OK按钮后再触发跳转 _dlgAlert.SetButton("OK", delegate { _dlgAlert.Dismiss(); _onComplete?.Invoke(); }); _dlgAlert.Show(); } } }
步骤2:修改按钮点击事件
// 把跳转逻辑封装成委托传递进去 fsp_SellDet_New_ByItemID fsp_SellDet_New_ByItemID = new fsp_SellDet_New_ByItemID(this, () => { Intent i = new Intent(this, typeof(SellDet)); StartActivity(i); Finish(); }); fsp_SellDet_New_ByItemID.ExecuteNonQuery(_SellID, _ItemID, _PodID, _ItemSellQty, _ItemPrice, _ItemPricePer, -_BaseDiscount, -_AdditionalDiscount, _ItemSum, _ItemVAT, _ItemCode, _ItemShortName, _ItemBrand, _ItemIssue);
如果不需要异常后跳转,只需要把catch里的_onComplete?.Invoke();删掉即可,这样异常时仅弹出Alert,不会执行跳转。
额外注意事项
如果你的数据库操作是耗时操作,建议把ExecuteNonQuery放到后台线程执行(比如用Task.Run或者AsyncTask),避免阻塞UI线程导致Alert弹出卡顿,同时要注意更新UI必须回到主线程(可以用RunOnUiThread)。
内容的提问来源于stack exchange,提问作者Valentino Gechev
相关产品推荐
相关产品推荐

