android 中处理崩溃异常并重启程序

亦余心之所善兮,虽九死其犹未悔。这篇文章主要讲述android 中处理崩溃异常并重启程序相关的知识,希望能为你提供帮助。
有时候由于测试不充分或者程序潜在的问题而导致程序异常崩溃,这个是令人无法接受的,在Android中怎样捕获程序的异常崩溃,然后进行一些必要的处理或重新启动
应用这个问题困恼了我很久,今天终于解决了该问题,写篇文章记录一下。
首先捕获程序崩溃的异常就必须了解一下Java中UncaughtExceptionHandler这个接口,android沿用了此接口,在android API中:

android 中处理崩溃异常并重启程序

文章图片

通过实现此接口,能够处理线程被一个无法捕捉的异常所终止的情况。如上所述的情况,handler将会报告线程终止和不明原因异常这个情况,如果没有自定义handler,
【android 中处理崩溃异常并重启程序】线程管理组就被默认为报告异常的handler。
ThreadGroup 这个类就是实现了UncaughtExceptionHandler这个接口,如果想捕获异常我们可以实现这个接口或者继承ThreadGroup,并重载uncaughtException方法。
在Java  API中对该接口描述的更详细:
android 中处理崩溃异常并重启程序

文章图片

我就不翻译了,太吃力了....%> _< %。在实现UncaughtExceptionHandler时,必须重载uncaughtException(Thread thread, Throwable ex) ,如果我们没有实现该接口
也就是没有显示捕捉异常,则ex为空,否则ex不为空,thread 则为出异常的线程。
接下来上代码,实现UncaughtExceptionHandler接口,显示处理线程异常终止的情况:
 
[java]  view plaincopy    
  1. public  class  UnCeHandler  implements  UncaughtExceptionHandler  {   
  2.            
  3.         private  Thread.UncaughtExceptionHandler  mDefaultHandler;        
  4.         public  static  final  String  TAG  =  "CatchExcep";    
  5.         CatchExcep  application;    
  6.            
  7.         public  UnCeHandler(CatchExcep  application){   
  8.                   //获取系统默认的UncaughtException处理器       
  9.                   mDefaultHandler  =  Thread.getDefaultUncaughtExceptionHandler();    
  10.                   this.application  =  application;    
  11.         }   
  12.            
  13.         @Override   
  14.         public  void  uncaughtException(Thread  thread,  Throwable  ex)  {           
  15.                 if(!handleException(ex)  & &   mDefaultHandler  !=  null){     
  16.                         //如果用户没有处理则让系统默认的异常处理器来处理       
  17.                         mDefaultHandler.uncaughtException(thread,  ex);                                
  18.                 }else{                 
  19.                         try{       
  20.                                 Thread.sleep(2000);        
  21.                         }catch  (InterruptedException  e){       
  22.                                 Log.e(TAG,  "error  :  ",  e);        
  23.                         }         
  24.                         Intent  intent  =  new  Intent(application.getApplicationContext(),  MainActivity.class);    
  25.                         PendingIntent  restartIntent  =  PendingIntent.getActivity(       
  26.                                         application.getApplicationContext(),  0,  intent,       
  27.                                         Intent.FLAG_ACTIVITY_NEW_TASK);                                                                                                  
  28.                         //退出程序                                                                                   
  29.                         AlarmManager  mgr  =  (AlarmManager)application.getSystemService(Context.ALARM_SERVICE);        
  30.                         mgr.set(AlarmManager.RTC,  System.currentTimeMillis()  +  1000,       
  31.                                         restartIntent);   //  1秒钟后重启应用     
  32.                         application.finishActivity();    
  33.                 }       
  34.         }   
  35.            
  36.         /**   
  37.           *  自定义错误处理,收集错误信息  发送错误报告等操作均在此完成.   
  38.           *     
  39.           *  @param  ex   
  40.           *  @return  true:如果处理了该异常信息; 否则返回false.   
  41.           */       
  42.         private  boolean  handleException(Throwable  ex)  {       
  43.                 if  (ex  ==  null)  {       
  44.                         return  false;        
  45.                 }       
  46.                 //使用Toast来显示异常信息       
  47.                 new  Thread(){       
  48.                         @Override       
  49.                         public  void  run()  {       
  50.                                 Looper.prepare();        
  51.                                 Toast.makeText(application.getApplicationContext(),  "很抱歉,程序出现异常,即将退出.",     
  52.                                                 Toast.LENGTH_SHORT).show();        
  53.                                 Looper.loop();        
  54.                         }     
  55.                 }.start();        
  56.                 return  true;        
  57.         }       
  58. }   

通过在android Application 这个全局类中处理异常,如果不知道Application的作用请查看一下此链接:Application 详解 
 
 
[java]  view plaincopy    
  1. public  class  CatchExcep  extends  Application{   
  2.            
  3.         ArrayList< Activity>   list  =  new  ArrayList< Activity> ();    
  4.            
  5.         public  void  init(){   
  6.                 //设置该CrashHandler为程序的默认处理器       
  7.                 UnCeHandler  catchExcep  =  new  UnCeHandler(this);    
  8.                 Thread.setDefaultUncaughtExceptionHandler(catchExcep);      
  9.         }   
  10.            
  11.         /** 
  12.           *  Activity关闭时,删除Activity列表中的Activity对象*/   
  13.         public  void  removeActivity(Activity  a){   
  14.                 list.remove(a);    
  15.         }   
  16.            
  17.         /** 
  18.           *  向Activity列表中添加Activity对象*/   
  19.         public  void  addActivity(Activity  a){   
  20.                 list.add(a);    
  21.         }   
  22.            
  23.         /** 
  24.           *  关闭Activity列表中的所有Activity*/   
  25.         public  void  finishActivity(){   
  26.                 for  (Activity  activity  :  list)  {       
  27.                         if  (null  !=  activity)  {       
  28.                                 activity.finish();        
  29.                         }       
  30.                 }   
  31.                 //杀死该应用进程   
  32.               android.os.Process.killProcess(android.os.Process.myPid());        
  33.         }   
  34. }   

然后人为制造一个异常:
 
 
[java]  view plaincopy    
  1.         Button  btn;    
  2.         TextView  tv;    
  3.         private  CatchExcep  application;    
  4.         @Override   
  5.         protected  void  onCreate(Bundle  savedInstanceState)  {   
  6.                 super.onCreate(savedInstanceState);    
  7.                 setContentView(R.layout.activity_main);    
  8.                    
  9.                 btn  =  (Button)findViewById(R.id.btn);    
  10.                 tv  =  (TextView)findViewById(R.id.tv);    
  11.                    
  12.                 application  =  (CatchExcep)getApplication();    
  13.                 application.init();    
  14.                 application.addActivity(this);    
  15.                    
  16.                 btn.setOnClickListener(this);                  
  17.         }         
  18.            
  19.         /** 
  20.           *  人为制造的异常*/   
  21.         public  void  press(){   
  22.                 new  Thread(new  Runnable()  {                     
  23.                         @Override   
  24.                         public  void  run()  {   
  25.                                 tv.setText("dfsd");    
  26.                         }   
  27.                 }).start();    
  28.         }   
  29.         @Override   
  30.         public  void  onClick(View  v)  {   
  31.                 press();    
  32.         }         
  33. }   

上诉代码就能够实现 应用出现无法捕捉的异常时,杀死当前进程,重新启动一个应用。
 
 
我之前困扰的地方:搜了很多资料,杀死异常进程,重新启动应用,网上应用都是通过Application对象调用startActivity(intent),然后杀死异常进程。但是我怎样试都不成功,
进程是杀死了,但是应用却没启动起来,如果不将异常进程杀死,那么关闭应用时就得关闭两次,显然不能够接受。网上的一些方法都是错误的:如下几篇博客:
http://blog.csdn.net/xianming01/article/details/7711160
http://blog.csdn.net/ryantang03/article/details/9336295?reload
他们的方法能够捕获异常,杀死异常进程,但是却不能够重新启动应用。
如何杀死异常进程,重启应用,就得使用PendingIntent,这个类是android中对Intent类的包装,具体了解我会在写一篇博客,自己也可以去查看android API。
通过AlarmManager 启动它,并且关闭打开的Activity杀死异常进程就能够实现重新启动应用。
参考链接:
http://zheyiw.iteye.com/blog/1670990




    推荐阅读