美文网首页代码片段分享
Xamarin Android Exception Handle

Xamarin Android Exception Handle

作者: 花艺荣 | 来源:发表于2019-12-26 14:05 被阅读0次

    转自: https://www.bbsmax.com/A/6pdDm3Xzw3/

    1. 参照java android的方式(这是坑 !!!)
      xamarin.android在很多时候都可以参考java android的代码,因此我按照 java android 的方式实现了一下“捕获未处理异常”
        public class CrashHandler:Thread.IUncaughtExceptionHandler
        {
            //系统默认的UncaughtException处理类
            private Thread.IUncaughtExceptionHandler mDefaultHandler;
            //CrashHandler实例
            private static CrashHandler INSTANCE = new CrashHandler();
            //程序的Context对象
            private Context mContext;
     
            /// <summary>
            /// 保证只有一个CrashHandler实例
            /// </summary>
            private CrashHandler()
            {
            }
     
            /// <summary>
            /// 获取CrashHandler实例 ,单例模式
            /// </summary>
            /// <returns></returns>
            public static CrashHandler GetInstance()
            {
                return INSTANCE;
            }
     
            public IntPtr Handle
            {
                get { return Thread.CurrentThread().Handle; }
            }
     
            public void Dispose()
            {
                this.Dispose();
            }
     
            /// <summary>
            /// 初始化
            /// </summary>
            /// <param name="context"></param>
            public void Init(Context context)
            {
                mContext = context;
                //获取系统默认的UncaughtException处理器
                mDefaultHandler = Thread.DefaultUncaughtExceptionHandler;
                //设置该CrashHandler为程序的默认处理器
                Thread.DefaultUncaughtExceptionHandler = this;
            }
     
            ///当UncaughtException发生时会转入该函数来处理
            public void UncaughtException(Thread thread, Throwable ex)
            {
                if (!HandleException(ex) && mDefaultHandler != null)
                {
                    //如果用户没有处理则让系统默认的异常处理器来处理
                    mDefaultHandler.UncaughtException(thread, ex);
                }
                else
                {
                    //退出程序
                    Android.OS.Process.KillProcess(Android.OS.Process.MyPid());
                    JavaSystem.Exit();
                }
            }
     
            /// <summary>
            /// 异常处理
            /// </summary>
            /// <param name="ex"></param>
            /// <returns>如果处理了该异常信息返回true; 否则返回false.</returns>
            private bool HandleException(Throwable ex)
            {
                if (ex == null)
                {
                    return false;
                }
     
                //处理程序(记录 异常、设备信息、时间等重要信息)
                //************
     
                //提示
                Task.Run(() =>
                {
                    Looper.Prepare();
                    //可以换成更友好的提示
                    Toast.MakeText(mContext, "很抱歉,程序出现异常,即将退出.", ToastLength.Long).Show();
                    Looper.Loop();
                });
     
                //停一会,让前面的操作做完
                System.Threading.Thread.Sleep();
     
                return true;
            }
        }
    
       [Application(Label = "MyApplication")]
        public class MyApplication : Application
        {
            public MyApplication(IntPtr javaReference, JniHandleOwnership transfer)
                : base(javaReference, transfer)
            {
            }
     
            public override void OnCreate()
            {
                base.OnCreate();
     
                CrashHandler crashHandler = CrashHandler.GetInstance();
                crashHandler.Init(ApplicationContext);
            }
     
        }
    

    通过实现Java.Lang.Thread.IUncaughtExceptionHandler接口自定义一个异常处理类CrashHandler,并替换掉Java.Lang.Thread.DefaultUncaughtExceptionHandler,
    当UncaughtException发生时会转入CrashHandler类中的UncaughtException方法中,在此处进行异常处理。
    然后制造一个异常throw new Exception("我是异常!");,本以为程序会进入CrashHandler类中的UncaughtException方法中,结果却不是,也就是说这种方式失败了,为什么? google后发现,IUncaughtExceptionHandler只能捕获到Dalvik runtime的异常,mono runtime中的C#异常,这个不起作用。
    因此这种方式不行,坑坑坑!

    1. 可行的捕捉方式
        [Application(Label = "MyApplication")]
        public class MyApplication : Application
        {
            public MyApplication(IntPtr javaReference, JniHandleOwnership transfer)
                : base(javaReference, transfer)
            {
            }
     
            public override void OnCreate()
            {
                base.OnCreate();
     
                //注册未处理异常事件
                AndroidEnvironment.UnhandledExceptionRaiser += AndroidEnvironment_UnhandledExceptionRaiser;
     
                //CrashHandler crashHandler = CrashHandler.GetInstance();
                //crashHandler.Init(ApplicationContext);
            }
     
            protected override void Dispose(bool disposing)
            {
                AndroidEnvironment.UnhandledExceptionRaiser -= AndroidEnvironment_UnhandledExceptionRaiser;
                base.Dispose(disposing);
            }
     
            void AndroidEnvironment_UnhandledExceptionRaiser(object sender, RaiseThrowableEventArgs e)
            {
                UnhandledExceptionHandler(e.Exception, e);
            }
     
            /// <summary>
            /// 处理未处理异常
            /// </summary>
            /// <param name="e"></param>
            private void UnhandledExceptionHandler(Exception ex, RaiseThrowableEventArgs e)
            {
                //处理程序(记录 异常、设备信息、时间等重要信息)
                //**************
     
                //提示
                Task.Run(() =>
                    {
                        Looper.Prepare();
                        //可以换成更友好的提示
                        Toast.MakeText(this, "很抱歉,程序出现异常,即将退出.", ToastLength.Long).Show();
                        Looper.Loop();
                    });
     
                //停一会,让前面的操作做完
                System.Threading.Thread.Sleep();
     
                e.Handled = true;
            }
        }
    

    注册未处理异常事件AndroidEnvironment.UnhandledExceptionRaiser += AndroidEnvironment_UnhandledExceptionRaiser; 在AndroidEnvironment_UnhandledExceptionRaiser中进行异常处理。
    制造一个异常throw new Exception("我是异常!");,妥妥的进入了AndroidEnvironment_UnhandledExceptionRaiser,OK,成

    相关文章

      网友评论

        本文标题:Xamarin Android Exception Handle

        本文链接:https://www.haomeiwen.com/subject/nkvbnctx.html