1. 程式人生 > >Android開發之全域性異常捕獲完美閃退

Android開發之全域性異常捕獲完美閃退

一、Application的生命週期

在說如何完美退出APP之前,我們先來講講Application的生命週期.

1、onCreate,app啟動的主入口,程式啟動的時候呼叫

  1. @Override
  2. publicvoid onCreate() {  
  3.     super.onCreate();  
  4. }  
2、onTerminate()  app停止的時候執行的方法,但並不一定會呼叫。當虛擬機器為別的應用程式騰出更大資源空間而終止當前應用程式的時候,是不會執行該方法的。
  1. publicvoid onTerminate() {  
  2.     super.onTerminate();  
  3.     System.exit(0);  
  4. }  

3、onLowMemory()當後臺程式已經終止資源還匱乏的時候,會呼叫這個方法,一般的程式會在這裡釋放一些不必要的資源
  1. @Override
  2. publicvoid onLowMemory() {  
  3.     super.onLowMemory();  
  4. }  

4、onConfigurationChanged(Configuration newConfig),當配置改變時呼叫的方法

  1. @Override
  2.     public
    void onConfigurationChanged(Configuration newConfig) {  
  3.         super.onConfigurationChanged(newConfig);  
  4.     }  
看完application的生命週期之後,想必大腿對於APP的啟動和退出有了一個大概的認識。我們常說activity,fragment,service,BroadcastReceiver的生命週期,但卻很少去了解application的生命週期。其實google設計的這個application類有很大的用處。一般來說,application代表整個應用程式,所以它就是一個全域性變數,所有的公共變數、需要全域性傳遞的數值都可以通過application來達到目的。而在activiiy中或者其他地方,我們都可以通過getApplication()或者mContext.getApplicationContext()來拿到application的例項。在這裡不在描述過多,網上百度可以找到很多的相關資訊。好了,下面進入正題。

二、全域性異常的捕獲及完美閃退出應用程式

直接上程式碼,程式碼大部分和網站別人的全域性異常捕獲一樣,但是,在初始化的時候,添加了application引數,在異常處理的方法也和別人的不一樣,詳細大家請仔細檢視註釋

  1. package com.batways.tnt.utils;  
  2. import java.io.File;  
  3. import java.io.FileOutputStream;  
  4. import java.io.PrintWriter;  
  5. import java.io.StringWriter;  
  6. import java.io.Writer;  
  7. import java.lang.Thread.UncaughtExceptionHandler;  
  8. import java.lang.reflect.Field;  
  9. import java.text.DateFormat;  
  10. import java.text.SimpleDateFormat;  
  11. import java.util.Date;  
  12. import java.util.HashMap;  
  13. import java.util.Map;  
  14. import com.batways.tnt.AppActivityManager;  
  15. import com.batways.tnt.TntApplication;  
  16. import com.batways.tnt.activity.MainActivity;  
  17. import com.batways.tnt.activity.ProductActivity;  
  18. import android.content.Context;  
  19. import android.content.pm.PackageInfo;  
  20. import android.content.pm.PackageManager;  
  21. import android.content.pm.PackageManager.NameNotFoundException;  
  22. import android.os.Build;  
  23. import android.os.Environment;  
  24. import android.util.Log;  
  25. import android.widget.Toast;  
  26. /** 
  27.  * @ClassName: CrashHandler 
  28.  * @author victor_freedom ([email protected]) 
  29.  * @createddate 2014-12-25 下午11:41:12 
  30.  * @Description: UncaughtException處理類,當程式發生Uncaught異常的時候,有該類來接管程式,並記錄傳送錯誤報告. 
  31.  */
  32. publicclass CrashHandler implements UncaughtExceptionHandler {  
  33.     publicstaticfinal String TAG = "CrashHandler";  
  34.     // CrashHandler 例項
  35.     privatestatic CrashHandler INSTANCE = new CrashHandler();  
  36.     // 程式的 Context 物件
  37.     private Context mContext;  
  38. <span>    </span>// app物件
  39.     private TntApplication app;  
  40.     // 系統預設的 UncaughtException 處理類
  41.     private Thread.UncaughtExceptionHandler mDefaultHandler;  
  42.     // 用來儲存裝置資訊和異常資訊
  43.     private Map<String, String> infos = new HashMap<String, String>();  
  44.     // 用於格式化日期,作為日誌檔名的一部分
  45.     private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");  
  46.     /** 保證只有一個 CrashHandler 例項 */
  47.     private CrashHandler() {  
  48.     }  
  49.     /** 獲取 CrashHandler 例項 ,單例模式 */
  50.     publicstatic CrashHandler getInstance() {  
  51.         return INSTANCE;  
  52.     }  
  53.     /** 
  54.      * @Title: init 
  55.      * @Description: 初始化 
  56.      * @param context 
  57.      * @param app 
  58.      *            傳入的app 
  59.      * @throws 
  60.      */
  61.     publicvoid init(Context context, TntApplication app) {  
  62.         // 傳入app物件,為完美終止app
  63.         this.app = app;  
  64.         mContext = context;  
  65.         // 獲取系統預設的 UncaughtException 處理器
  66.         mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();  
  67.         // 設定該 CrashHandler 為程式的預設處理器
  68.         Thread.setDefaultUncaughtExceptionHandler(this);  
  69.     }  
  70.     /** 
  71.      * 當 UncaughtException 發生時會轉入該函式來處理 
  72.      */
  73.     @Override
  74.     publicvoid uncaughtException(Thread thread, Throwable ex) {  
  75.         if (!handleException(ex) && mDefaultHandler != null) {  
  76.             // 如果使用者沒有處理則讓系統預設的異常處理器來處理
  77.             mDefaultHandler.uncaughtException(thread, ex);  
  78.         } else {  
  79.             // 釋放資源不能像常規的那樣在activity的onDestroy方法裡面執行,因為如果出現全域性異常捕獲,activity的關閉有時候是不會再走相關的生命週期函式的(onDesktroy,onStop,onPause等)。
  80.             // 這裡是博主在退出app之前需要釋放掉的一些資源,通過之前講的AppActivityManager來拿到對應的例項activity釋放裡面的資源,然後呼叫AppExit退出應用程式
  81.             ProductActivity activitys = (ProductActivity) AppActivityManager  
  82.                     .getAppActivityManager().getActivity(ProductActivity.class);  
  83.             activitys.offline();  
  84.             MainActivity activity = (MainActivity) AppActivityManager  
  85.                     .getAppActivityManager().getActivity(MainActivity.class);