一、前言

android中如果出现了未处理的异常,程序会闪退,这是非常不好的用户体验,很多用户会因此卸载APP,因此未处理的异常是应该尽力避免的。

有些很难避免的异常(如:IO、网络等),应在代码中进行捕捉并做相应的处理,以阻止程序崩溃闪退。

但是“没有任何程序是完美的”,况且各式各样的android终端也大大增加了异常的出现概率,就连强大的QQ、微信等不也会闪退嘛!

这时就需要全局捕获未处理的异常,并进行处理。(注意:本文中的处理方式并不能阻止APP闪退

处理方式:收集异常信息、当前场景[时间、硬件参数],在合适的时机上传至服务端

作用:1、便于下一版本修复bug 2、便于帮助用户解决异常造成的困难

二、参照java android的方式(这是坑啊)

xamarin.android在很多时候都可以参考java android的代码,因此我按照java android的方式实现了一下“捕获未处理异常”

    [Obsolete]    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(1);            }        }        /// <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(2000);            return true;        }    }
View Code
[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);        }    }
View Code

通过实现Java.Lang.Thread.IUncaughtExceptionHandler接口自定义一个异常处理类CrashHandler,并替换掉Java.Lang.Thread.DefaultUncaughtExceptionHandler,

当UncaughtException发生时会转入CrashHandler类中的UncaughtException方法中,在此处进行异常处理。

然后制造一个异常throw new Exception("我是异常!");,本以为程序会进入CrashHandler类中的UncaughtException方法中,结果却不是,也就是说这种方式失败了,为什么? google后发现,IUncaughtExceptionHandler只能捕获到Dalvik runtime的异常,mono runtime中的C#异常,这个不起作用。

因此这种方式不行,坑坑坑!

三、正确的捕捉方式

[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(2000);            e.Handled = true;        }    }
View Code

注册未处理异常事件AndroidEnvironment.UnhandledExceptionRaiser += AndroidEnvironment_UnhandledExceptionRaiser; 在AndroidEnvironment_UnhandledExceptionRaiser中进行异常处理。

制造一个异常throw new Exception("我是异常!");,妥妥的进入了AndroidEnvironment_UnhandledExceptionRaiser,OK,成功!

说明:捕获异常后的具体处理,无非就是读取硬件信息、时间、异常信息,并保存至本地,在合适的时机上传至服务端,为了突出重点,我在这里就不实现了。

源码下载

https://github.com/jordanqin/CatchException

参考:

http://forums.xamarin.com/discussion/4576/application-excepionhandler
http://blog.csdn.net/liuhe688/article/details/6584143

如果你觉得文章对你有帮助,可以点击旁边的“推荐”按钮,这样会让更多需要的人有机会看到

更多相关文章

  1. Android:Service生命周期方法与Service启动方式bindService与Star
  2. Android恶意程序泛滥,安全问题或制约进一步发展
  3. Android(安卓)刘海屏适配方案---NotchTools,适配国内四大厂商(华
  4. 视频直播软件开发:Android客户端接入谷歌支付的实现流程
  5. Android(安卓)图片压缩策略详解,有效解决 Android(安卓)程序 OOM
  6. Android程序员面试造航母,工作拧螺丝?各种缘由大揭秘!
  7. Android程序开发初级教程(二)
  8. Android(安卓)手机端与服务器端通过http交换数据 Json
  9. Android进阶:十二、最简单的方式实现自定义阴影效果

随机推荐

  1. Android 快速启动
  2. AES Android 加密
  3. Android Dependencies 是什么?
  4. android 入门
  5. Android点击效果加边框
  6. Android VideoView orientation change w
  7. 76 Android BroadcastReceiver简单使用
  8. Android(安卓)Studio代码自动提示无效(not
  9. Android之GLES2.0显示图片测试代码
  10. 在Android WebView中设置Cookie