一、前言

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();
}
} /// <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#异常,这个不起作用。

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

三、正确的捕捉方式

[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,成功!

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

源码下载

https://github.com/jordanqin/CatchException

参考:

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

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

Xamarin.Android-捕获未处理异常(全局异常)的更多相关文章

  1. java android 捕获未处理异常

    1. 定义一个异常处理类 public class ExceptionHandler implements Thread.UncaughtExceptionHandler { public Excep ...

  2. android 捕获未try的异常

    1.Thread.UncaughtExceptionHandler java里有很多异常如:空指针异常,越界异常,数值转换异常,除0异常,数据库异常等等.如果自己没有try / catch 那么线程就 ...

  3. android 捕获未try的异常、抓取崩溃日志

    1.Thread.UncaughtExceptionHandler java里有很多异常如:空指针异常,越界异常,数值转换异常,除0异常,数据库异常等等.如果自己没有try / catch 那么线程就 ...

  4. Application中捕获APP中的全局异常

    package com.example.administrator.mystudent; import android.app.Application; import android.util.Log ...

  5. 【Android】 -- 使用UncaughtExceptionHandler捕捉全局异常

    在综合统计SDK(欧盟统计局的朋友,百度统计)之后.有一个非常有利的功能测试:错误分析.此功能可以在程序的执行中遇到崩溃(runtimeException)反馈给server,帮助开发者提高产品.多功 ...

  6. 如何捕获Wince下form程序的全局异常

    前言 上两篇文章我们总结了在winform程序下如何捕获全局的异常.那么同样的问题,在wince下我们如何来处理呢?用相同的代码来处理可以吗? 答案是否定的,上面的方案1完全不能解决wince下的情况 ...

  7. 【spring】-- springboot配置全局异常处理器

    一.为什么要使用全局异常处理器? 什么是全局异常处理器? 就是把错误异常统一处理的方法. 应用场景: 1.当你使用jsr303参数校验器,如果参数校验不通过会抛异常,而且无法使用try-catch语句 ...

  8. springmvc中拦截器与springmvc全局异常处理器的问题

    最近在做一个练手的小项目, 系统架构中用了springmvc的全局异常处理器, 做了系统的统一异常处理. 后来加入了springmvc的拦截器, 为了一些需求, 在拦截器中的 preHandle 方法 ...

  9. Android程序捕获未处理异常,处理与第三方方法冲突时的异常传递

    自己的android程序对异常进行了处理,用的也是网上比较流行的CrashHandler,代码如下,就是出现了未处理的异常程序退出,并收集收集设备信息和错误信息仪器保存到SD卡,这里没有上传到服务器. ...

随机推荐

  1. 微软.NET Core RC2正式发布,横跨所有平台

    .NET官方博客宣布了<Announcing .NET Core RC2 and .NET Core SDK Preview 1>,正式如期发布了.NET Core RC2, 现在可以放心 ...

  2. Anders Hejlsberg 技术理想架构开发传奇

    Anders Hejlsberg(安德斯-海森博格) 坐在自己的办公室,双眼直直的盯着前方.他要做一个决定,决定自己未来的命运和理想.这是1996年一个普通的下午,几个小时前,他刚与比尔-盖茨结束了 ...

  3. bzoj1723--前缀和(水题)

    题目大意: 你难以想象贝茜看到一只妖精在牧场出现时是多么的惊讶.她不是傻瓜,立即猛扑过去,用她那灵活的牛蹄抓住了那只妖精.     "你可以许一个愿望,傻大个儿!"妖精说.     ...

  4. 【Java每日一题】20170106

    20170105问题解析请点击今日问题下方的"[Java每日一题]20170106"查看(问题解析在公众号首发,公众号ID:weknow619) package Jan2017; ...

  5. BPM配置故事之案例7-公式计算

    行政主管发来邮件.要求物资明细表增加"单价""总价"."单价"由其审批时填写,"总价"根据"单价"与 ...

  6. linux系统oracle-ora12505问题解决方案一

    说明:(1)Linux版本 Linux version 2.6.32.12-0.7-default (geeko@buildhost) (gcc version 4.3.4 [gcc-4_3-bran ...

  7. EntityFramework 6 + Mysql 生成POCOs

    问题 使用EDMX文件 EF Power Tools参数不正确的解决方法 对于"异常来自 HRESULT:0x80070057 (E_INVALIDARG)",有方法说" ...

  8. 【腾讯Bugly干货分享】移动App入侵与逆向破解技术-iOS篇

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/577e0acc896e9ebb6865f321 如果您有耐心看完这篇文章,您将懂 ...

  9. .NET全栈开发工程师学习路径

    PS:最近一直反复地看博客园以前发布的一条.NET全栈开发工程师的招聘启事,觉得这是我看过最有创意也最朴实的一个招聘启事,更为重要的是它更像是一个技术提纲,能够指引我们的学习和提升,现在转载过来与各位 ...

  10. C#开发奇技淫巧三:把dll放在不同的目录让你的程序更整洁

    系列文章 C#开发奇技淫巧一:调试windows系统服务 C#开发奇技淫巧二:根据dll文件加载C++或者Delphi插件 C#开发奇技淫巧三:把dll放在不同的目录让你的程序更整洁 程序目录的整理 ...