package jjp.ccpg.ens;import android.content.Context;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import android.os.Build;import android.os.Environment;import android.os.Looper;import android.os.Process;import android.text.TextUtils;import android.widget.Toast;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.PrintWriter;import java.io.StringWriter;import java.io.Writer;import java.lang.reflect.Field;import java.text.SimpleDateFormat;import java.util.Date;import java.util.HashMap;import java.util.Locale;import java.util.Map;/** * ===================================== * 作    者: 江朋 258183284@qq.com * 版    本:1.0.4 * 创建日期:2018/8/30 * 描    述: * ===================================== */public class CrashHandler implements Thread.UncaughtExceptionHandler{    private static CrashHandler sInstance = null;    private Thread.UncaughtExceptionHandler mDefaultHandler;    private Context mContext;    // 保存手机信息和异常信息    private Map mMessage = new HashMap<>();    public static CrashHandler getInstance() {        if (sInstance == null) {            synchronized (CrashHandler.class) {                if (sInstance == null) {                    synchronized (CrashHandler.class) {                        sInstance = new CrashHandler();                    }                }            }        }        return sInstance;    }    private CrashHandler() {    }    /**     * 初始化默认异常捕获     *     * @param context context     */    public void init(Context context) {        mContext = context;        // 获取默认异常处理器        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();        // 将此类设为默认异常处理器        Thread.setDefaultUncaughtExceptionHandler(this);    }    @Override    public void uncaughtException(Thread t, Throwable e) {        if (!handleException(e)) {            // 未经过人为处理,则调用系统默认处理异常,弹出系统强制关闭的对话框            if (mDefaultHandler != null) {                mDefaultHandler.uncaughtException(t, e);            }        } else {            // 已经人为处理,系统自己退出            try {                Thread.sleep(1000);            } catch (InterruptedException e1) {                e1.printStackTrace();            }            Process.killProcess(Process.myPid());            System.exit(1);        }    }    /**     * 是否人为捕获异常     *     * @param e Throwable     * @return true:已处理 false:未处理     */    private boolean handleException(Throwable e) {        if (e == null) {// 异常是否为空            return false;        }        new Thread() {// 在主线程中弹出提示            @Override            public void run() {                Looper.prepare();                Toast.makeText(mContext, "捕获到异常", Toast.LENGTH_SHORT).show();                Looper.loop();            }        }.start();        collectErrorMessages();        saveErrorMessages(e);        return false;    }    /**     * 1.收集错误信息     */    private void collectErrorMessages() {        PackageManager pm = mContext.getPackageManager();        try {            PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES);            if (pi != null) {                String versionName = TextUtils.isEmpty(pi.versionName) ? "null" : pi.versionName;                String versionCode = "" + pi.versionCode;                mMessage.put("versionName", versionName);                mMessage.put("versionCode", versionCode);            }            // 通过反射拿到错误信息            Field[] fields = Build.class.getFields();            if (fields != null && fields.length > 0) {                for (Field field : fields) {                    field.setAccessible(true);                    try {                        mMessage.put(field.getName(), field.get(null).toString());                    } catch (IllegalAccessException e) {                        e.printStackTrace();                    }                }            }        } catch (PackageManager.NameNotFoundException e) {            e.printStackTrace();        }    }    /**     * 2.保存错误信息     *     * @param e Throwable     */    private void saveErrorMessages(Throwable e) {        StringBuilder sb = new StringBuilder();        for (Map.Entry entry : mMessage.entrySet()) {            String key = entry.getKey();            String value = entry.getValue();            sb.append(key).append("=").append(value).append("\n");        }        Writer writer = new StringWriter();        PrintWriter pw = new PrintWriter(writer);        e.printStackTrace(pw);        Throwable cause = e.getCause();        // 循环取出Cause        while (cause != null) {            cause.printStackTrace(pw);            cause = e.getCause();        }        pw.close();        String result = writer.toString();        sb.append(result);        String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA).format(new Date());        String fileName = "crash-" + time + "-" + System.currentTimeMillis() + ".log";        // 有无SD卡        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {            String path = Environment.getExternalStorageDirectory().getPath() + "crash/";            File dir = new File(path);            if (!dir.exists()) dir.mkdirs();            FileOutputStream fos = null;            try {                fos = new FileOutputStream(path + fileName);                fos.write(sb.toString().getBytes());            } catch (Exception e1) {                e1.printStackTrace();            } finally {                if (fos != null) {                    try {                        fos.close();                    } catch (IOException e1) {                        e1.printStackTrace();                    }                }            }        }}}

更多相关文章

  1. System Permissions—— android系统权限
  2. Android 坐标系统
  3. Android获取系统时间
  4. 小编程(三):用户登录注册界面开发及用户信息管理案例代码详解
  5. Android 进阶—— Android 系统安全机制之Apk签名详解及Android
  6. Android之地理信息服务·Android的定位服务
  7. Android手机操作系统中实现图片浏览
  8. Android系统结构
  9. Android实现电池管理系统

随机推荐

  1. Flutter 导航管理(一)
  2. Android串口盒子+扫码枪开发
  3. Andrid Tv开发中下载第三方应用,解析包失
  4. android开发之流量监控
  5. Android 底部弹出自定义Dialog(支付宝微
  6. android的两种异步机制
  7. Android中Intent组件详解 .
  8. Android(安卓)input处理机制(四)线程安全
  9. Android 查看/data/data文件夹并取回文件
  10. 2019最新Android算法相关面试大全,请查收