1. 程式人生 > >Android 全域性異常捕獲

Android 全域性異常捕獲

全域性異常捕獲

廢話不多說,直接上程式碼

package com.util;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;

import android.content.Context;

/**
 *  全域性異常捕獲控制代碼類
 */
public class CrashHandler implements UncaughtExceptionHandler {

    public
static final String TAG = "CrashHandler"; public static final boolean DEBUG = false; // 是否開啟日誌輸出,在Debug狀態下開啟, // 在Release狀態下關閉以提高程式效能 private static CrashHandler crashHandler; private Thread.UncaughtExceptionHandler exceptionHandler; // 系統預設的UncaughtExceptionHandler
private Context context; /** * 私有建構函式 */ private CrashHandler() { } /** * @return 單例 */ public static CrashHandler getInstance() { if (crashHandler == null) { crashHandler = new CrashHandler(); } return crashHandler; } /** * @param
context * 上下文物件 */
public void init(Context context) { this.context = context; exceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); // 獲取系統預設的UncaughtExceptionHandler Thread.setDefaultUncaughtExceptionHandler(this); // 設定本類物件crashHandler為程式的預設處理器 } /** * 當異常發生時,捕獲異常 * * @param thread * 執行緒 * @param ex * 異常 */ @Override public void uncaughtException(Thread thread, Throwable ex) { if (!handleException(thread, ex) && exceptionHandler != null) { exceptionHandler.uncaughtException(thread, ex); // 如果使用者沒有處理則讓系統預設的異常處理器來處理 } else { try { Thread.sleep(3000); } catch (InterruptedException e) { SLog.Console("===============CrashHandler================"); SLog.saveException(e); SLog.Console("==============CrashHandlerEnd=============="); } } } /** * 自定義異常處理 * * @param ex * 異常 * @return boolean 是否處理 */ private boolean handleException(Thread thread, Throwable ex) { if (ex == null) { return true; } StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw, true); ex.printStackTrace(pw); pw.flush(); sw.flush(); this.saveInfo2File(ex); // 儲存錯誤報告檔案 return true; } /** * 儲存異常資訊到檔案中 * * @param ex * 異常 * @return String 異常資訊 */ public String saveInfo2File(final Throwable ex) { // if (MainApplication.getInstance().isTest) { // new Thread(){ // @Override // public void run() { // Looper.prepare(); // String errorMsg=MessageUtils.getExcptionToastMessage(ex); // Toast.makeText(MainApplication.getInstance(), "很抱歉,程式出現"+errorMsg+",即將退出.", // Toast.LENGTH_LONG).show(); // Looper.loop(); // } // }.start(); // } Writer writer = new StringWriter(); PrintWriter printWriter = new PrintWriter(writer); ex.printStackTrace(printWriter); Throwable cause = ex.getCause(); while (cause != null) { cause.printStackTrace(printWriter); cause = cause.getCause(); } String info = writer.toString(); printWriter.close(); FileUtil.saveLog("=================CrashInfo==============="); FileUtil.saveLog(info); SLog.Console(info); FileUtil.saveLog("================CrashInfoEnd============="); return info; } }

然後在MainApplication中新增對應的宣告即可

package com.example.zxingdemo;

import android.app.Application;

import com.util.CrashHandler;
import com.util.PathUtil;
import com.util.SLog;

public class MainApplication extends Application {

    private static MainApplication mApplication;

    @Override
    public void onCreate() {
        super.onCreate();
        mApplication = this;
        PathUtil.getInstance().init(mApplication);
        SLog.cleanOutOfDateLog();
        // 新增全域性異常捕獲
        CrashHandler crashHandler = CrashHandler.getInstance();
        crashHandler.init(getApplicationContext());
    }

    public static synchronized MainApplication getInstance() {
        return mApplication;
    }
}

最後一定要注意在Manifest裡邊指定Application

<application
        android:name="com.example.zxingdemo.MainApplication"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:screenOrientation="portrait" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.karics.library.zxing.android.CaptureActivity"
            android:theme="@android:style/Theme.NoTitleBar"
            android:screenOrientation="portrait" >
        </activity>
    </application>