代码片段分享

Xamarin Android Exception Handle

2019-12-26  本文已影响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,成

上一篇下一篇

猜你喜欢

热点阅读