Android 异常处理

Android 捕获异常的原理

Android 的异常分为两种,Java层的异常和Native层的异常

Java层异常捕获

Java层默认通过调用Thread.setDafaultUncaughtException 注册一个UncaughtExceptionHandler来捕获异常,这个Handler可以抓到所有线程的未处理异常。

```javafinal Thread.UncaughtExceptionHandler oldHandler = Thread.getDefaultUncaughtExceptionHandler();Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {@Overridepublic void uncaughtException(Thread thread, Throwable throwable) {// 崩溃前的处理// ...// 既可以收到Exception, 也可以收到Error            /*调用默认处理,杀死进程*/oldHandler.uncaughtException(thread, throwable);}});```

也可以注册针对指定线程的异常处理Handler,如

    Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {@Overridepublic void uncaughtException(Thread thread, Throwable throwable) {// 崩溃前的处理// ...// 既可以收到Exception, 也可以收到Errorif( /*这是一个致命错误*/ ) {//调用默认处理,杀死进程Thread.getDefaultUncaughtExceptionHandler().uncaughtException(thread, throwable);} else {// 什么也不处理的话, 当前线程被终止,但是整个进程可以继续运行}}});

Native层异常

Native层异常时通过信号来通知。要捕获native异常,需要注册信号回调。
方法如下:

    static struct sigaction g_oldCSSigAction[8] = {0};void CrashSaver_handleSignal(int sig, siginfo_t* info, void* context);// 注册信号函数void CrashSaver_install(){    // 保存信号的默认行为对象    memset(g_oldCSSigAction, 0, sizeof(g_oldCSSigAction));    sigaction(SIGTRAP, NULL, &g_oldCSSigAction[0]);    sigaction(SIGABRT, NULL, &g_oldCSSigAction[1]);    sigaction(SIGILL, NULL, &g_oldCSSigAction[2]);    sigaction(SIGSEGV, NULL, &g_oldCSSigAction[3]);    sigaction(SIGFPE, NULL, &g_oldCSSigAction[4]);    sigaction(SIGBUS, NULL, &g_oldCSSigAction[5]);    sigaction(SIGPIPE, NULL, &g_oldCSSigAction[6]);    sigaction(SIGSYS, NULL, &g_oldCSSigAction[7]);        // 创建 信号行为对象    struct sigaction newSigAction;           sigemptyset(&newSigAction.sa_mask);    newSigAction.sa_flags = SA_SIGINFO;    /*设置信号处理函数*/    newSigAction.sa_sigaction = CrashSaver_handleSignal;        // 注册信号新的行为对象    sigaction(SIGTRAP, &newSigAction, NULL);    sigaction(SIGABRT, &newSigAction, NULL);    sigaction(SIGILL, &newSigAction, NULL);    sigaction(SIGSEGV, &newSigAction, NULL);    sigaction(SIGFPE, &newSigAction, NULL);    sigaction(SIGBUS, &newSigAction, NULL);    sigaction(SIGPIPE, &newSigAction, NULL);    sigaction(SIGSYS, &newSigAction, NULL);}

回调处理函数:

   void CrashSaver_handleSignal(int sig, siginfo_t* info, void* context){// sig  触发的信号ID   如 SIGABRT、SIGSEGV等    // info  对此信号的描述信息    // context 信号发生的上下文。比如各种寄存器信息。此结构和具体的CPU平台有关        // 此处增加处理逻辑        CrashSaver_uninstall(); /*反注册*/    raise(signum); /*调用系统默认信号处理*/} 

反注册函数

    void CrashSaver_uninstall(){    sigaction(SIGTRAP, &g_oldCSSigAction[0], NULL);    sigaction(SIGABRT, &g_oldCSSigAction[1], NULL);    sigaction(SIGILL , &g_oldCSSigAction[2], NULL);    sigaction(SIGSEGV, &g_oldCSSigAction[3], NULL);    sigaction(SIGFPE, &g_oldCSSigAction[4], NULL);    sigaction(SIGBUS, &g_oldCSSigAction[5], NULL);    sigaction(SIGPIPE, &g_oldCSSigAction[6], NULL);    sigaction(SIGSYS, &g_oldCSSigAction[7], NULL);    memset(g_oldCSSigAction, 0, sizeof(g_oldCSSigAction));}

Crash SDK

  1. Bugly
    腾讯出品的SDK,对Crash搜集的体验非常赞,能搜集到JNI层的奔溃以及监控线上的ANR问题。

  2. Crashlytics
    国外的一个SDK,我自己没用过,但是用过的朋友对它的评价颇高。

  3. ARCA
    一个开源的崩溃日志搜集器,轻松让你实现客户端的崩溃日志上传到后台,如果你不喜欢接入别人家的SDK,可以使用它。有一个不足之处,就是它搜集不到JNI层的奔溃。

  4. 异常处理

更多相关文章

  1. Android(安卓)处理启动页(Splash)白屏问题
  2. 很实用的android按键处理
  3. 关于“Only the original thread that created a view hierarchy
  4. android动画效果处理
  5. Android(安卓)Market google play store帐号注册方法流程 及发布
  6. Android(安卓)Handler 消息机制原理解析
  7. android之RecycleView之ItemTouchHelper 处理拖拽、滑动删除
  8. 初识RatingBar
  9. Android通知Notification学习 及 无法通知解决方案

随机推荐

  1. [Traceview]android性能测试
  2. 在Android Sudio中使用Uiautomator
  3. Android开发(二十九)——layout_weight的含
  4. Android(安卓)Socket编程
  5. Android之创建程序快捷方式
  6. Android中文翻译组
  7. AndroidManifest.xml配置文件详解
  8. Android(安卓)极光推送快速接入
  9. Android(安卓)XML解析技术-自eoe
  10. Ubuntu下Android NDK的安装及配置