package com.anyun.exam.lib.crash; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.Build; import android.os.Looper; import android.widget.Toast; import com.anyun.basecommonlib.MyLog; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; import java.lang.reflect.Field; import java.text.SimpleDateFormat; import java.util.HashMap; import java.util.Map; /** * MyApplication2 * Created by lzw on 2019/9/27. 10:22:20 * 邮箱:632393724@qq.com * All Rights Saved! Chongqing AnYun Tech co. LTD */ public class CrashHandler implements Thread.UncaughtExceptionHandler { private static CrashHandler mInstance = new CrashHandler(); private Thread.UncaughtExceptionHandler mDefaultCrashHandler; private Context mContext; private SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private HashMap infos = new HashMap<>(); /** * 私有构造函数 **/ private CrashHandler() { } public static CrashHandler getInstance() { return mInstance; } public void init(Context context) { this.mContext = context; mDefaultCrashHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(this); } @Override public void uncaughtException(Thread t, Throwable e) { if (!handleException(e) && mDefaultCrashHandler != null) { //如果用户没有处理异常则让系统默认的异常处理器去处理异常 mDefaultCrashHandler.uncaughtException(t, e); } else { try { Thread.sleep(3000); } catch (InterruptedException ex) { ex.printStackTrace(); } //退出程序 android.os.Process.killProcess(android.os.Process.myPid()); System.exit(1); } } private boolean handleException(Throwable ex) { if (ex == null) { return false; } //使用Toast显示异常信息 new Thread(){ @Override public void run() { Looper.prepare(); Toast.makeText(mContext,"很抱歉,程序出现异常,即将退出!",Toast.LENGTH_SHORT).show(); Looper.loop(); } }.start(); //收集设备信息 collectDeviceInfo(); saveCrashInfo2File(ex); return true; } private void saveCrashInfo2File(Throwable ex) { StringBuffer stringBuffer = new StringBuffer(); for (Map.Entry entry : infos.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); stringBuffer.append(key + "=" + value + "\n"); } 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(); } printWriter.close(); String result = writer.toString(); stringBuffer.append(result); MyLog.i("crash", stringBuffer.toString()); } private void collectDeviceInfo() { if (mContext != null) { PackageManager packageManager = mContext.getPackageManager(); try { PackageInfo packageInfo = packageManager.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES); if (packageInfo != null) { String versionCode = Long.toString(packageInfo.versionCode); String versionName = packageInfo.versionName; infos.put("versionName", versionName); infos.put("versionCode", versionCode); } } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } Field[] fields = Build.class.getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); try { infos.put(field.getName(), field.get(null).toString()); } catch (IllegalAccessException e) { e.printStackTrace(); } } } } }