首页 > 其他 > 详细

CrashHandler实例

时间:2014-04-08 22:29:29      阅读:659      评论:0      收藏:0      [点我收藏+]
bubuko.com,布布扣
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Field;
import java.util.Properties;
import org.json.JSONObject;

import com.yuexue.tool.L;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.os.Process;

/**
 * @brief 全局异常处理
 */
public class CrashHandler implements UncaughtExceptionHandler {
    /**
     * @brief Debug Log tag
     * */
    public static final String TAG = "CrashHandler";
    /**
     * @brief 系统默认的UncaughtException处理类
     * */
    private Thread.UncaughtExceptionHandler mDefaultHandler;
    /**
     * @brief CrashHandler实例
     * */
    private static CrashHandler INSTANCE;
    /**
     * @brief 程序的Context对象
     * */
    private Context mContext;
    /**
     * @brief 使用Properties来保存设备的信息和错误堆栈信息
     * */
    private Properties mDeviceCrashInfo = new Properties();
    private static final String VERSION_NAME = "versionName";
    private static final String VERSION_CODE = "versionCode";
    private static final String STACK_TRACE = "STACK_TRACE";

    /**
     * @brief保证只有一个CrashHandler实例
     * */
    private CrashHandler() {
        
    }

    /**
     * @brief 获取CrashHandler实例 ,单例模式
     * */
    public static CrashHandler getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new CrashHandler();
        }
        return INSTANCE;
    }

    /**
     * @brief 初始化,注册Context对象, 获取系统默认的UncaughtException处理器,
     *        设置该CrashHandler为程序的默认处理器
     * 
     * @param ctx
     */
    public void init(Context ctx) {
        mContext = ctx;
        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(this);
    }

    /**
     * @brief 当UncaughtException发生时会转入该函数来处理
     */
    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        if (!handleException(ex) && mDefaultHandler != null) {
            // 如果用户没有处理则让系统默认的异常处理器来处理
            mDefaultHandler.uncaughtException(thread, ex);
        } else {
            // Sleep一会后结束程序,此处可以测试一下决定时间,因为不同sdk机制不同
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                L.e("uncaughtException", e.getMessage());
            }
            Process.killProcess(android.os.Process.myPid());
            System.exit(10);
        }
    }

    /**
     * @brief 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. 开发者可以根据自己的情况来自定义异常处理逻辑
     * 
     * @param ex
     * @return true:如果处理了该异常信息;否则返回false
     */
    private boolean handleException(Throwable ex) {
        if (ex == null) {
            return true;
        }
        mDeviceCrashInfo.put(STACK_TRACE, ex.getMessage());
        // 收集设备信息
        collectCrashDeviceInfo(mContext);

        JSONObject jsonObject = new JSONObject(mDeviceCrashInfo);
        L.d("DeviceCrashInfo", jsonObject.toString());
        // 走友盟统计,暂时省略了其他处理
        //其他可增加处理,如存储成文件提交到自己服务端,错误日志打包,下次提交,都可以在下面增加处理机制
//         MobclickAgent.reportError(mContext,jsonObject.toString());
        
        return true;
    }

    /**
     * @brief 收集程序崩溃的设备信息
     * 
     * @param ctx
     */
    public void collectCrashDeviceInfo(Context ctx) {
        try {
            PackageManager pm = ctx.getPackageManager();
            PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(),
                    PackageManager.GET_ACTIVITIES);
            if (null != pi) {
                mDeviceCrashInfo.put(VERSION_NAME,
                        pi.versionName == null ? "not set" : pi.versionName);
                mDeviceCrashInfo.put(VERSION_CODE, pi.versionCode + "");
            }
        } catch (NameNotFoundException e) {
            L.e(TAG, "Error while collect package info: " + e.getMessage());
        }
        // 使用反射来收集设备信息.在Build类中包含各种设备信息,
        // 例如: 系统版本号,设备生产商 等帮助调试程序的有用信息
        Field[] fields = Build.class.getDeclaredFields();
        for (Field field : fields) {
            try {
                field.setAccessible(true);
                mDeviceCrashInfo.put(field.getName(), field.get(null)
                        .toString());
            } catch (Exception e) {
                L.e(TAG, "Error while collect crash info: " + e.getMessage());
            }

        }
    }
}
bubuko.com,布布扣

 

CrashHandler实例,布布扣,bubuko.com

CrashHandler实例

原文:http://www.cnblogs.com/haoxiqiang/p/3652637.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!