Android一點 異常收集

異常捕捉有助於我們調試錯誤,但是app發佈了自己看不到log怎麼辦?這時我們就需要AppException異常收集器了

異常的處理主要是實現UncaughtExceptionHandler這個接口,並重載uncaughtException方法,通過Throwable來獲取異常的信息。不明白UncaughtExceptionHandler的可以百度查查

AppException

package com.example.test;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Field;

import org.json.JSONObject;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.telephony.TelephonyManager;

public class AppException implements UncaughtExceptionHandler {
    /** 程序的Context對象 ,傳入ApplicationContext */
    private Context context;
    private DeviceInfo devInfo;

    /** 系統默認的UncaughtException處理類 */
    private Thread.UncaughtExceptionHandler mDefaultHandler;
    /** CrashHandler實例 */
    private static AppException appException;

    /** 保證只有一個CrashHandler實例 */
    private AppException() {
    }

    /** 獲取CrashHandler實例 ,單例模式 */

    public static AppException getInstance() {

        if (appException == null) {
            appException = new AppException();
        }

        return appException;
    }

    /**
     * 初始化,註冊Context對象, 獲取系統默認的UncaughtException處理器, 設置該CrashHandler爲程序的默認處理器
     *
     * @param context
     */

    public void init(Context context) {

        this.context = context;
        devInfo=collectDeviceInfo();

        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();

        Thread.setDefaultUncaughtExceptionHandler(this);


    }

    /**
     * 當UncaughtException發生時會轉入該函數來處理
     */
    @Override
    public void uncaughtException(Thread thread, Throwable ex) {

        handleException(ex);
        if (mDefaultHandler != null) {
            // 如果用戶沒有處理則讓系統默認的異常處理器來處理
            mDefaultHandler.uncaughtException(thread, ex);
        }
    }

    /**
     * 自定義錯誤處理,收集錯誤信息 發送錯誤報告等操作均在此完成. 開發者可以根據自己的情況來自定義異常處理邏輯
     */
    public String handleException(Throwable e) {

        StringBuffer sb = new StringBuffer();

        // 獲取classname、報錯的哪一行等
        // String className = stacks[0].getFileName();
        // String methodName = stacks[0].getMethodName();
        // int lineNumber = stacks[0].getLineNumber();
        // System.out.println("ElementException:"+"className:"+className+" methodName:"+methodName+" lineNumber:"+lineNumber);

        // 獲取具體的報錯信息
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        e.printStackTrace(pw);
//      System.out.println("crashMessage:" + sw.toString());

        // 直接定位報錯信息
//      System.out.println("getCause:" + e.getMessage().toString());

        sb.append("sdkVersion:"+devInfo.getOsVersion()+"\n")
        .append("versionName:"+devInfo.getVersionName()+"\n")
        .append("versionCode:"+devInfo.getVersionCode()+"\n")
        .append("manufacturer:"+devInfo.getManufacturer()+"\n")
        .append("model:"+devInfo.getModel()+"\n")
        .append("deviceId:"+devInfo.getDeviceId()+"\n")
        .append("Exception:"+sw.toString());

        System.out.println("crashMessage:" + sb.toString());

        return sb.toString();
    }

    /**
     * 手機設備信息
     */
    public DeviceInfo collectDeviceInfo() {

        // TODO Auto-generated method stub
        try {
            PackageManager pm = context.getPackageManager();
            PackageInfo pi = pm.getPackageInfo(context.getPackageName(),
                    PackageManager.GET_ACTIVITIES);
            if (pi != null) {

                DeviceInfo devInfo=new DeviceInfo();

//              devInfo.setOsVersion(android.os.Build.VERSION.SDK);
                devInfo.setOsVersion(android.os.Build.VERSION.RELEASE);


                String versionName = pi.versionName == null ? "null": pi.versionName;
                String versionCode = pi.versionCode + "";

                devInfo.setVersionName(versionName);
                devInfo.setVersionCode(versionCode);

                TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);  
                StringBuilder sb = new StringBuilder();  
                devInfo.setDeviceId(tm.getDeviceId());

                // 獲取手機型號
                devInfo.setModel(android.os.Build.MODEL);
                //獲取手機廠商:
                devInfo.setManufacturer(android.os.Build.MANUFACTURER);

                System.out.println("devInfo:"+devInfo);

                return devInfo;

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;


    }

    /**
       * 獲取手機的硬件信息
       * 
       * @return 
       */
      public String getMobileInfo() {
        JSONObject json = new JSONObject();
        // 通過反射獲取系統的硬件信息

        Field[] fields = Build.class.getDeclaredFields();
        for (Field field : fields) {
          try {
            field.setAccessible(true);
            json.put(field.getName(), field.get(null).toString());

          } catch (Exception e) {
              e.printStackTrace();
          }
        }

        System.out.println("getMobileInfo:"+json.toString());

        return json.toString();
      }


    public class DeviceInfo{
        private String osVersion;
        private String versionName;
        private String versionCode;
        private String deviceId;
        private String model;
        private String manufacturer;

        public String getOsVersion() {
            return osVersion;
        }
        public void setOsVersion(String osVersion) {
            this.osVersion = osVersion;
        }
        public String getVersionName() {
            return versionName;
        }
        public void setVersionName(String versionName) {
            this.versionName = versionName;
        }
        public String getVersionCode() {
            return versionCode;
        }
        public void setVersionCode(String versionCode) {
            this.versionCode = versionCode;
        }
        public String getDeviceId() {
            return deviceId;
        }
        public void setDeviceId(String deviceId) {
            this.deviceId = deviceId;
        }
        public String getModel() {
            return model;
        }
        public void setModel(String model) {
            this.model = model;
        }
        public String getManufacturer() {
            return manufacturer;
        }
        public void setManufacturer(String manufacturer) {
            this.manufacturer = manufacturer;
        }
        @Override
        public String toString() {
            return "DeviceInfo [osVersion=" + osVersion + ", versionName="
                    + versionName + ", versionCode=" + versionCode
                    + ", deviceId=" + deviceId + ", model=" + model
                    + ", manufacturer=" + manufacturer + "]";
        }

    }
}

獲取設備信息還需要權限

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

使用的時候我們只要傳入ApplicationContext

AppException.getInstance().init(getApplicationContext());

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章