废话不多哔哔,直接上工具类
/**
* 全局捕获异常
* 当程序发生Uncaught异常的时候,有该类来接管程序,并记录错误日志
*/
public class CrashHandler_Ma {
public static String TAG = "MyCrash";
// 用来存储设备信息和异常信息
private static Map<String, String> map = new HashMap<>();
//使用volatile关键字保其可见性
volatile private static CrashHandler_Ma instance = null;
private CrashHandler_Ma() {
}
public static CrashHandler_Ma getInstance() {
try {
if (instance != null) {//懒汉式
} else {
//创建实例之前可能会有一些准备性的耗时工作
Thread.sleep(300);
synchronized (CrashHandler_Ma.class) {
if (instance == null) {//二次检查
instance = new CrashHandler_Ma();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return instance;
}
public void init(Context context) {
// 设置该CrashHandler为程序的默认处理器
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable ex) {
try {
Log_Ma.e(TAG, "uncaughtException: " + ex);
if (ex != null) {
// 使用Toast来显示异常信息
/*new Thread() {
@Override
public void run() {
Looper.prepare();
Toast.makeText(context, "APP运行缓慢,自动调整中。", Toast.LENGTH_LONG).show();
Looper.loop();
}
}.start();*/
saveCrashInfoFile(ex, context);
SystemClock.sleep(1000);
restartApp();
}
} catch (Exception e) {
SystemClock.sleep(1000);
// 退出程序
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(1);
}
}
});
}
/**
* 保存错误信息到文件中
*
* @return 返回文件名称, 便于将文件传送到服务器
*/
private void saveCrashInfoFile(Throwable ex, Context context) {
try {
map.put("versionName", AppUtils_Ma.getVersionName(context));
map.put("versionCode", AppUtils_Ma.getVersionCode(context) + "");
/*收集设备参数信息*/
Field[] fields = Build.class.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
map.put(field.getName(), field.get(null).toString());
}
} catch (Exception e) {
}
StringBuffer sb = new StringBuffer();
try {
SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date = sDateFormat.format(new Date());
sb.append("\r\n" + date + "\n");
for (Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
sb.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.flush();
printWriter.close();
String result = writer.toString();
sb.append(result);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
ActivityManager activityManager = (ActivityManager) App.getContext().getSystemService(Context.ACTIVITY_SERVICE);
ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo();
activityManager.getMemoryInfo(info);
long mm = 1024 * 1024;
sb.append("\n应用在本机能够获取的最大内存:" + DoubleUtil.div(Runtime.getRuntime().maxMemory(), mm, 2) + "m")
.append("\n系统剩余内存: " + DoubleUtil.div(info.availMem, mm, 2) + "m")
.append("\n系统是否处于低内存运行:" + info.lowMemory)
.append("\n系统总的内存:" + DoubleUtil.div(info.totalMem, mm, 2) + "m")
.append("\n临界值,达到这个值,进程就要被杀死:" + DoubleUtil.div(info.threshold, mm, 2) + "m");
}
} catch (Exception e) {
sb.append("an error occured while writing file...\r\n");
}
LiteOrmDBUtil.insert(new Bean_ERROR(0, sb.toString()));
sb.setLength(0);
}
/*重启应用(按需要添加是否重启应用)*/
public void restartApp() {
ActivityManager_Singe.getInstance().finishAllActivity();
Intent intent = new Intent(App.getContext(), Activity_Splash.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
App.getContext().startActivity(intent);
android.os.Process.killProcess(android.os.Process.myPid());
}
}
使用方法:
在Application里面的onCreate()方法里添加
CrashHandler_Ma.getInstance().init(this);
其实里面有一个这个方法:LiteOrmDBUtil.insert(new Bean_ERROR(0, sb.toString()));
我其实是把这个错误信息保存到数据库里面了,等到下次进首页的时候,把数据库里面的错误信息传到服务器,便于后续分析,这也是常用的一种手段,还有一些人集成第三方,也可以,这里只讲手动的步骤。