目录

Android异常捕获:Thread.UncaughtExceptionHandler使用详解


一、前言:

  • Android开发过程中难免会出现一些bug,测试环境和生产环境的差异也会导致出现的一些异常,我们开发者需要去捕获这些异常,收集这些异常信息,以便自己更好的解决问题,给予用户更友好的体验。
  • Thread.UncaughtExceptionHandler 这个类是android官方提供给我们的专门用来捕获异常的神器,网络的文章也很多,本次我们将直接通过学习Google官方API文档来进行学习。

二、UncaughtExceptionHandler

  • 官方介绍为:

  • Interface for handlers invoked when a Thread abruptly terminates due to an uncaught exception.

  • When a thread is about to terminate due to an uncaught exception the Java Virtual Machine will query the thread for its UncaughtExceptionHandler using getUncaughtExceptionHandler() and will invoke the handler’s uncaughtException method, passing the thread and the exception as arguments. If a thread has not had its UncaughtExceptionHandler explicitly set, then its ThreadGroup object acts as its UncaughtExceptionHandler. If the ThreadGroup object has no special requirements for dealing with the exception, it can forward the invocation to the default uncaught exception handler.

大意是:

  • UncaughtExceptionHandler接口用于处理因为一个未捕获的异常而导致一个线程突然终止问题。
  • 当一个线程因为一个未捕获的异常即将终止时,Java虚拟机将通过调用getUncaughtExceptionHandler() 函数去查询该线程的UncaughtExceptionHandler并调用处理器的 uncaughtException方法将线程及异常信息通过参数的形式传递进去。如果一个线程没有明确设置一个UncaughtExceptionHandler,那么ThreadGroup对象将会代替UncaughtExceptionHandler完成该行为。如果ThreadGroup没有明确指定处理该异常,ThreadGroup将转发给默认的处理未捕获的异常的处理器。

异常回调:uncaughtException

  • uncaughtException (Thread t, Throwable e) 是一个抽象方法,当给定的线程因为发生了未捕获的异常而导致终止时将通过该方法将线程对象和异常对象传递进来。

设置默认未捕获异常处理器:setDefaultUncaughtExceptionHandler

  • void setDefaultUncaughtExceptionHandler (Thread.UncaughtExceptionHandler eh)
  • 设置一个处理者当一个线程突然因为一个未捕获的异常而终止时将自动被调用。
  • 未捕获的异常处理的控制第一个被当前线程处理,如果该线程没有捕获并处理该异常,其将被线程的ThreadGroup对象处理,最后被默认的未捕获异常处理器处理。
  • 通过设置默认的未捕获异常的处理器,对于那些早已被系统提供了默认的未捕获异常处理器的线程,一个应用可以改变处理未捕获的异常的方式,例如记录到指定的设备或者文件。

三、代码实例

  • 代码如下

      	import android.app.Application;
      	import android.content.Context;
      	import android.content.Intent;
    
      	import com.ruilin.veni.activity.WelcomeNewActivity;
    
      	import bingo.okt.utils.log.ELog;
    
      	public class CrashManager implements Thread.UncaughtExceptionHandler {
      			public static final String TAG = "CrashHandler";
      			// CrashHandler实例
      			private static CrashManager instance;
      			// 程序的Context对象
      			private Application application;
      			// 系统默认的UncaughtException处理类
      			private Thread.UncaughtExceptionHandler mDefaultHandler;
    
      			/**
      			 * 保证只有一个CrashHandler实例
      			 */
      			private CrashManager(Context context) {
      					application = (Application) context.getApplicationContext();
      					mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
      					Thread.setDefaultUncaughtExceptionHandler(this);
      			}
    
      			/**
      			 * 获取CrashHandler实例 ,单例模式
      			 */
      			public static CrashManager getInstance(Context context) {
      					CrashManager inst = instance;
      					if (inst == null) {
      							synchronized (CrashManager.class) {
      									inst = instance;
      									if (inst == null) {
      											inst = new CrashManager(context.getApplicationContext());
      											instance = inst;
      									}
      							}
      					}
      					return inst;
      			}
    
      			/**
      			 * 当UncaughtException发生时会转入该函数来处理
      			 */
      			@Override
      			public void uncaughtException(Thread thread, Throwable ex) {
      					ELog.e(TAG, thread.getName(), ex);
      					Intent intent = new Intent(application, WelcomeNewActivity.class);
      					intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
      					application.startActivity(intent);
      					OApp.CloseApp();
      	//        mDefaultHandler.uncaughtException(thread, ex);
      			}
    
      	}
    
  • application中初始化

      @Override
      	public void onCreate() {
      			super.onCreate();
      			CrashManager.getInstance(this);