Xamarin Android Exception Handle
2019-12-26 本文已影响0人
花艺荣
转自: https://www.bbsmax.com/A/6pdDm3Xzw3/
- 参照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#异常,这个不起作用。
因此这种方式不行,坑坑坑!
- 可行的捕捉方式
[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,成