zoukankan      html  css  js  c++  java
  • android 中处理崩溃异常并重启程序

    转:http://blog.csdn.net/cym_lmy/article/details/24704089

    有时候由于测试不充分或者程序潜在的问题而导致程序异常崩溃,这个是令人无法接受的,在android中怎样捕获程序的异常崩溃,然后进行一些必要的处理或重新启动

    应用这个问题困恼了我很久,今天终于解决了该问题,写篇文章记录一下。

    首先捕获程序崩溃的异常就必须了解一下java中UncaughtExceptionHandler这个接口,android沿用了此接口,在android API中:

    通过实现此接口,能够处理线程被一个无法捕捉的异常所终止的情况。如上所述的情况,handler将会报告线程终止和不明原因异常这个情况,如果没有自定义handler,

    线程管理组就被默认为报告异常的handler。

    ThreadGroup 这个类就是实现了UncaughtExceptionHandler这个接口,如果想捕获异常我们可以实现这个接口或者继承ThreadGroup,并重载uncaughtException方法。

    在java API中对该接口描述的更详细:

    我就不翻译了,太吃力了....%>_<%。在实现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. new AlertDialog.Builder(mContext)
      .setCancelable(false)
      .setTitle("提示信息");
      .create().show();

    54.                 Looper.loop();    
    55.             }   
    56.         }.start();    
    57.         return true;    
    58.     }    
    59. }  


    通过在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

  • 相关阅读:
    PAT (Basic Level) Practise 1013 数素数
    PAT (Basic Level) Practise 1014 福尔摩斯的约会
    codeforces 814B.An express train to reveries 解题报告
    KMP算法
    rsync工具
    codeforces 777C.Alyona and Spreadsheet 解题报告
    codeforces 798C.Mike and gcd problem 解题报告
    nginx + tomcat多实例
    MongoDB副本集
    指针的艺术(转载)
  • 原文地址:https://www.cnblogs.com/tmlee/p/4992237.html
Copyright © 2011-2022 走看看