Thread.UncaughtExceptionHandler

来源:互联网 发布:java final 成员变量 编辑:程序博客网 时间:2024/05/22 16:38

1. 自定义Application继承Application 在清单文件中将默认的Application的android:name=“”替换成自定义的Application对象名称即可
在Oncreate中写入要实现的内容

2.
在编写APK程序时,通常会导致程序崩溃的异常,在通常情况下这些异常不能被捕获到,利用Thread.UncaughtExceptionHandler就可以捕获到这些异常。从名字就可以看出来UncaughtExceptionHandler是针对某个线程而言的,同时Thread提供了3个相关的方法:

1. void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh) //为一个线程设置一个Handler
2. Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() //获取该线程的handler

3. static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)


//为一个线程设置一个默认的Handler,在程序不能捕获而退出,并且么有其他的handler时被调用

所以只要通过set方法,为一个线程设置一个handler就可以在程序异常退出时,捕获改异常,Demo1:


Thread thread = new thread(new Runnable(){
public void run() {
//Do something can throw runtime exception.
}
});
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler(){
@Override
public void uncaughtException(Thread thread, Throwable ex) {
//TODO
System.out.println(ex.getLocalizedMessage());
});

线程的运行时异常就会被捕获,你就可以对捕获到异常进行处理


但是,由于在android编程中,大量使用线程,如果统一处理呢?因为主线程只有一个,我们可以在主线程里处理。
我们可以在主activity启动时的oncreate方法里面添加下面代码

Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread thread, Throwable ex) {
//TODO
System.out.println(ex.getLocalizedMessage());
finish();
}
});

这样就可以捕获大部分的运行时异常了

 

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Thread的run方法是不抛出任何检查型异常(checked exception)的,但是它自身却可能因为一个异常而被终止,导致这个线程的终结。最麻烦的是,在线程中抛出的异常即使使用try...catch也无法截获,因此可能导致一些问题出现,比如异常的时候无法回收一些系统资源,或者没有关闭当前的连接等等。

JDK5.0之前,不能为单独的Thread设置UncaughtExceptionHandler,也不能指定一个默认的UncaughtExceptionHandler。为了可以设置一个UncaughtExceptionHandler,需要去继承ThreadGroup并覆写uncaughtException方法。

在JDK5.0中,我们通过Thread的实例方法setUncaughtExceptionHandler,可以为任何一个Thread设置一个UncaughtExceptionHandler。当然你也可以为所有Thread设置一个默认的UncaughtExceptionHandler,通过调用Thread.setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)方法,这是Thread的一个static方法。

定义一个Handler类必须实现Thread.UncaughtExceptionHandler接口的void uncaughtException(Thread t, Throwable e)方法。如果不设置一个Handler,那么单个Thread的Handler是null。但是,如果这个单个线程是ThreadGroup中的一个Thread,那么这个线程将使用ThreadGroup的UncaughtExceptionHandler。ThreadGroup自身已经实现了Thread.UncaughtExceptionHandler接口。

這樣就夠了


uncaughtException(Thread a, Throwable e)可以拿到Thread,所以在uncaughtException释放相关资源是最好的办法。

总之,JDK5.0中Thread及其相关的辅助功能得到了加强,为我们提供了很多便利和安全的解决方案:)


import java.lang.Thread.UncaughtExceptionHandler;

public class
ThreadTest {

 
public static void
main(String[] args) {
    ErrHandler handle
=null
;
    ThreadA a
=null
;

    a
= new
ThreadA();
    handle
=new
ErrHandler();
    a.setUncaughtExceptionHandler(handle);
// 加入定义的ErrHandler

    a.start();

  }

}

/**

* 自定义的一个UncaughtExceptionHandler
*/
class ErrHandlerimplements UncaughtExceptionHandler {
 
/**

   * 这里可以做任何针对异常的处理,比如记录日志等等
  
*/
 
publicvoid uncaughtException(Thread a, Throwable e) {
    System.out.println(
"This is:"+ a.getName()+ ",Message:"

       
+ e.getMessage());
    e.printStackTrace();
  }
}

/**

* 拥有UncaughtExceptionHandler的线程
*/
class ThreadAextends Thread {

 
public
ThreadA() {

  }

 
public void
run() {

   
double i = 12/ 0;// 抛出异常的地方

  }

}

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

在Java 的异常处理机制中:
如果抛出的是Exception异常的话,必须有try..catch..进行处理,属于checked exception。
如果抛出的是RuntimeException异常的话,则不是必须进行try..catch..异常处理,发生异常之后将由JVM进行处理,属于unchecked exception。
注意:为了保证程序的健壮性,建议抛出RunntimeException异常,也使用try..catch..进行处理。

这两者最本质的区别在于设计者认为使用者是否能够并且应该处理这个异常。

Java 异常的分类:
基类为:Throwable
Error 和 Exception 继承于Throwable
RuntimeException和IOException等继承Exception
其中,Error和RuntimeException及其子类属于unchecked exception, 而其他异常为checked exception。


Error类描述了Java运行系统中的内部错误以及资源耗尽的情形,应用程序不应该抛出这种类型的对象(一般是由Java虚拟机抛出)。如果出现这种错误,除了尽力使程序安全退出外,在其他方面是无能为力的。所以,在我们在程序设计时,应该更关注Exception体系。

RuntimeExcption体系,包括错误的类型转换,数组越界访问和试图访问空指针等等。如果出现RuntimeException,那么一定是你自己的错误。

其他非RuntimeExcetpion(IOException等等),这类异常一般是外部错误,例如试图从文件尾后读取数据等,这并不是程序本身的错误,而是在应用环境中出现的外部错误。

在Android开发中,常常会出现uncheched Exception 导致程序的crash,为了提供良好的用户体验,并对出错的信息进行收集,以便对程序进行改进,提高程序的健壮性。因此,常使用Thread.UncaughtExceptionHandler来进行处理。

首先需要继承Thread.UncaughtExceptionHandler类

[java] view plaincopyprint?
  1. publicclass CrashHandler implements Thread.UncaughtExceptionHandler { 
  2.     publicstatic final String TAG = CrashHandler.class.getSimpleName(); 
  3.     privatestatic CrashHandler INSTANCE = new CrashHandler(); 
  4.     private Context mContext; 
  5.     private Thread.UncaughtExceptionHandler mDefaultHandler; 
  6.  
  7.  
  8.     private CrashHandler() { 
  9.     } 
  10.  
  11.  
  12.     publicstatic CrashHandler getInstance() { 
  13.         return INSTANCE; 
  14.     } 
  15.  
  16.  
  17.     publicvoid init(Context ctx) { 
  18.         mContext = ctx; 
  19.         mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); 
  20.         Thread.setDefaultUncaughtExceptionHandler(this); 
  21.     } 
  22.  
  23.  
  24.     @Override 
  25.     publicvoid uncaughtException(Thread thread, Throwable ex) { 
  26.         // if (!handleException(ex) && mDefaultHandler != null) { 
  27.         // mDefaultHandler.uncaughtException(thread, ex); 
  28.         // } else { 
  29.         // android.os.Process.killProcess(android.os.Process.myPid()); 
  30.         // System.exit(10); 
  31.         // } 
  32.         System.out.println("uncaughtException"); 
  33.  
  34.  
  35.         new Thread() { 
  36.             @Override 
  37.             public void run() { 
  38.                 Looper.prepare(); 
  39.                 new AlertDialog.Builder(mContext).setTitle("提示").setCancelable(false
  40.                         .setMessage("程序崩溃了...").setNeutralButton("我知道了",new OnClickListener() { 
  41.                             @Override 
  42.                             public void onClick(DialogInterface dialog,int which) { 
  43.                                 System.exit(0); 
  44.                             } 
  45.                         }) 
  46.                         .create().show(); 
  47.                 Looper.loop(); 
  48.             } 
  49.         }.start(); 
  50.     } 
  51.  
  52.  
  53.     /**
  54.      * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. 开发者可以根据自己的情况来自定义异常处理逻辑
  55.      *
  56.      * @param ex
  57.      * @return true:如果处理了该异常信息;否则返回false
  58.      */ 
  59.     privateboolean handleException(Throwable ex) { 
  60.         if (ex ==null) { 
  61.             return true
  62.         } 
  63.         // new Handler(Looper.getMainLooper()).post(new Runnable() { 
  64.         // @Override 
  65.         // public void run() { 
  66.         // new AlertDialog.Builder(mContext).setTitle("提示") 
  67.         // .setMessage("程序崩溃了...").setNeutralButton("我知道了", null) 
  68.         // .create().show(); 
  69.         // } 
  70.         // }); 
  71.  
  72.  
  73.         return true
  74.     } 


然后在Application类中进行注册

[java] view plaincopyprint?
  1. publicclass MyApplication extends Application{ 
  2.  
  3.  
  4.     @Override 
  5.     publicvoid onCreate(){ 
  6.     super.onCreate(); 
  7.         initErrorHandler(); 
  8.     } 
  9.  
  10.  
  11.    privatevoid initErrorHandler(){ 
  12.     CrashHandler handler = CrashHandler.getInstance(); 
  13.     handler.init(this); 
  14.    } 

 

0 0
原创粉丝点击