Android系統獲取應用的Crash信息

hiyounger 8年前發布 | 6K 次閱讀 安卓開發 Android開發 移動開發

Android應用不可避免的都會發生crash,即程序崩潰

可能是系統或程序有bug等內部原因,或者是網絡狀況不佳等外部原因

當應用發生crash時,如果只是你一個人使用的應用,那自然容易檢測出原因,可是如果應用有廣泛的使用者,面對市面上眾多的Rom和機型,就需要一個個獲取發生crash時的系統情況了,將異常信息記錄下來并發送到服務器,供開發者了解情況并調試

Android提供有默認的異常處理方法,也可以自定義異常處理方法

在Thread類下有如下方法用來設置自定義異常處理器

public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler handler) {
    Thread.defaultUncaughtHandler = handler;
}

當crash發生時,系統會回調UncaughtExceptionHandler的如下方法,我們就需要來重寫該方法

public void uncaughtException(Thread thread, Throwable throwable){

}

因此,現在需要進行的步驟是:

1. 實現Thread.UncaughtExceptionHandler接口,自定義異常處理器

2. 重寫uncaughtException方法

3. 在uncaughtException方法中將crash信息以及當前手機信息保存到文本中,然后將文本打包發送到服務器

新建CrashHandler類繼承于Thread.UncaughtExceptionHandler

/**
 * Crash處理 CZY
 * Created by ZY on 2016/8/27.
 */
public class CrashHandler implements Thread.UncaughtExceptionHandler {

    //定義文件存放路徑
    private static final String PATH = Environment.getExternalStorageDirectory().getPath() + "/CrashInfo/";

    //定義文件后綴
    private static final String FILE_NAME_SUFFIX = ".txt";

    //系統默認的異常處理器
    private Thread.UncaughtExceptionHandler defaultCrashHandler;

    private static final String TAG = "CrashHandler";

    private static CrashHandler crashHandler = new CrashHandler();

    //私有化構造函數
    private CrashHandler() {
    }

    //獲取實例
    public static CrashHandler getInstance() {
        return crashHandler;
    }

    public void init() {
        defaultCrashHandler = Thread.getDefaultUncaughtExceptionHandler();
        //設置系統的默認異常處理器
        Thread.setDefaultUncaughtExceptionHandler(this);
    }

    @Override
    public void uncaughtException(Thread thread, Throwable throwable) {
        //記錄異常信息到本地文本中
        dumpExceptionToSDCard(throwable);
        if (defaultCrashHandler != null) {
            //如果在自定義異常處理器之前,系統有自己的默認異常處理器的話,調用它來處理異常信息
            defaultCrashHandler.uncaughtException(thread, throwable);
        } else {
            Process.killProcess(Process.myPid());
        }
    }

    //記錄異常信息到本地文本中
    private void dumpExceptionToSDCard(Throwable throwable) {
        //如果SD卡非正常掛載,則用Log輸出異常信息
        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            Log.e(TAG, "SD卡出錯");
            return;
        }
        File dir = new File(PATH);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        long currentTime = System.currentTimeMillis();
        String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(currentTime));
        //建立記錄Crash信息的文本
        File file = new File(PATH + time + FILE_NAME_SUFFIX);
        try {
            PrintWriter printWriter = new PrintWriter(new BufferedWriter(new FileWriter(file)));
            printWriter.println(time);
            dumpPhoneInfo(printWriter);
            printWriter.println();
            throwable.printStackTrace(printWriter);
            printWriter.close();
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "記錄Crash信息失敗");
        }
    }

    //記錄手機信息
    private void dumpPhoneInfo(PrintWriter printWriter) {
        //系統版本號
        printWriter.print("OS Version:");
        printWriter.print(Build.VERSION.RELEASE);
        printWriter.print("_");
        printWriter.println(Build.VERSION.SDK_INT);
        //硬件制造商
        printWriter.print("Vendor:");
        printWriter.println(Build.MANUFACTURER);
        //系統定制商
        printWriter.print("Brand:");
        printWriter.println(Build.BRAND);
    }

}

采用了單例模式,每個方法的作用也都注釋了其作用

然后,選擇在Application中初始化CrashHandler

所以需要自定義Application

/**
 * Created by ZY on 2016/8/27.
 */
public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        CrashHandler crashHandler = CrashHandler.getInstance();
        crashHandler.init();
    }

}

需要在AndroidManifest.xml文件中聲明之

即在application標簽下添加以下一行語句

android:name=".MyApplication"

此外,因為還涉及到了內存卡寫操作,所以需要聲明下權限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

然后,在主布局文件中聲明個按鈕,在點擊后拋出一個自定義異常

findViewById(R.id.crashTest).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                throw new RuntimeException("自定義異常");
            }
        });

點擊后程序異常退出,打開手機的文件內容管理器

可以看到多了一個CrashInfo文件夾

這里寫圖片描述

保存異常信息的文件

這里寫圖片描述

異常信息

這里寫圖片描述

這要,就獲取到了異常信息,這里只是將信息保存到了SD卡上,在實際開發中再添加上傳到服務器的操作即可

 

來自:http://www.jianshu.com/p/780b222185ea

 

 本文由用戶 hiyounger 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!