android app 捕获全局异常,保存成文件
16lz
2021-01-26
CrashHandler :
package com.example.petrochina_oil;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.Process;import android.text.TextUtils;import android.util.Log;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.List;import java.util.Locale;import java.util.Map;import okhttp3.Call;import okhttp3.Callback;import okhttp3.FormBody;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.Response;/** * 作用: * 1.收集错误信息 * 2.保存错误信息 */public class CrashHandler implements Thread.UncaughtExceptionHandler { private static CrashHandler sInstance = null; private Thread.UncaughtExceptionHandler mDefaultHandler; private Context mContext; // 保存手机信息和异常信息 protected Map mMessage = new HashMap<>(); protected _Functions functions = new _Functions(); String path = Environment.getExternalStorageDirectory().getPath() + "/mileCrash/"; public static CrashHandler getInstance() { 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); List log_files = functions.getFilesAllName(path); Log.d("init", "init"); for (int i = 0; i < log_files.size(); i++) { postToServer(log_files.get(i)); } } @Override public void uncaughtException(Thread t, Throwable e) { if (!handleException(e)) { // 未经过人为处理,则调用系统默认处理异常,弹出系统强制关闭的对话框 if (mDefaultHandler != null) { mDefaultHandler.uncaughtException(t, e); } } else { // 已经人为处理,系统自己退出 try { Thread.sleep(3000); } 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; } Log.e("CrashHandler", "捕捉到异常"); 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()); Log.e("collectErrorMessages", "收集异常信息"); } catch (IllegalAccessException e) { e.printStackTrace(); } } } } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } } /** * 保存错误信息 * * @param e Throwable */ private void saveErrorMessages(Throwable e) { Log.e("saveErrorMessages", "保存异常信息"); StringBuffer sb = new StringBuffer(); for (Map.Entry entry : mMessage.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); sb.append(key + "=" + value + "\n"); } Writer writer = new StringWriter(); PrintWriter printWriter = new PrintWriter(writer); e.printStackTrace(printWriter); Throwable cause = e.getCause(); while (cause != null) { cause.printStackTrace(printWriter); cause = cause.getCause(); } printWriter.close(); String result = writer.toString(); sb.append(result); Log.e("saveErrorMessages", "异常信息: " + result); saveToFile(result); } private void postToServer(final String file) { Log.d("crashPostToServer", "start"); String strUrlPath = "http://119.3.56.22/index.php?m=Api&c=Alert&a=postAlert"; OkHttpClient client = new OkHttpClient();//创建OkHttpClient对象。 FormBody.Builder formBody = new FormBody.Builder();//创建表单请求体 //formBody.add("mid",Config.get("mac"));//传递键值对参数 formBody.add("code", "1001");//传递键值对参数 String result = functions.getStrFromFile2("", file); Log.e("postToServer", "异常信息: " + result); formBody.add("description", result);//传递键值对参数 Request request = new Request.Builder()//创建Request 对象。 .url(strUrlPath) .post(formBody.build())//传递请求体 .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) {//回调的方法执行在子线程。 if (response.code() == 200) { functions.deleteSingleFile(file); } } } }); } private void saveToFile(String result) { String time = new SimpleDateFormat("yyyy-MM-dd HH_mm_ss", Locale.CHINA).format(new Date()); String fileName = time + ".log"; functions.writeStrToFile2(result, fileName, path, false); }}
调用:
CrashHandler.getInstance().init(this);
更多相关文章
- 读取APK中versionCode信息
- android练习一之保存用户名
- Android_rom存储,sp存储,sdcard存储
- 保存数据到手机内存代码优化(QQ登录保存密码)
- Android(安卓)电视退出程序Animation
- android bitmap序列号
- android打开文件、保存对话框、创建新文件夹对话框
- Android中保存图片到本地功能实现
- Android(安卓)程式开发:(廿一)消息传递 —— 21.3 使用Intent发送短