• 错误Log日志的收集


    1.在Application里面初始化

    AppCrashHandler.getInstance(this);

    2.创建一个类
    package com.lvshandian.partylive.utils;

    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.FilenameFilter;
    import java.io.PrintWriter;
    import java.io.StringWriter;
    import java.io.Writer;
    import java.lang.Thread.UncaughtExceptionHandler;
    import java.lang.reflect.Field;
    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Map;

    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.content.Intent;
    import android.content.pm.PackageInfo;
    import android.content.pm.PackageManager;
    import android.content.pm.PackageManager.NameNotFoundException;
    import android.os.Build;
    import android.os.Environment;
    import android.os.Looper;
    import android.os.SystemClock;
    import android.util.Log;
    import android.widget.Toast;

    /**
    * <h3>全局捕获异常</h3> <br>
    * 当程序发生Uncaught异常的时候,有该类来接管程序,并记录错误日志
    */
    @SuppressLint("SimpleDateFormat")
    public class CrashHandler implements UncaughtExceptionHandler {

    public static String TAG = "MyCrash";
    // 系统默认的UncaughtException处理类
    private Thread.UncaughtExceptionHandler mDefaultHandler;

    private static CrashHandler instance = new CrashHandler();
    private Context mContext;

    // 用来存储设备信息和异常信息
    private Map<String, String> infos = new HashMap<String, String>();

    // 用于格式化日期,作为日志文件名的一部分
    private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

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

    /**
    * 获取CrashHandler实例 ,单例模式
    */
    public static CrashHandler getInstance() {
    return instance;
    }

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

    /**
    * UncaughtException发生时会转入该函数来处理
    */
    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
    if (!handleException(ex) && mDefaultHandler != null) {
    // 如果用户没有处理则让系统默认的异常处理器来处理
    mDefaultHandler.uncaughtException(thread, ex);
    } else {
    SystemClock.sleep(3000);
    // 退出程序
    android.os.Process.killProcess(android.os.Process.myPid());
    System.exit(1);
    }
    }

    /**
    * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
    *
    * @param ex
    * @return true:如果处理了该异常信息; 否则返回false.
    */
    private boolean handleException(Throwable ex) {
    if (ex == null)
    return false;

    try {
    // 使用Toast来显示异常信息
    new Thread() {

    @Override
    public void run() {
    Looper.prepare();
    Toast.makeText(mContext, "很抱歉,程序出现异常,即将重启.", Toast.LENGTH_LONG).show();
    Looper.loop();
         }
    }.start();
    // 收集设备参数信息
    collectDeviceInfo(mContext);
    // 保存日志文件
    saveCrashInfoFile(ex);
    // 重启应用(按需要添加是否重启应用)
    Intent intent =
    mContext.getPackageManager().getLaunchIntentForPackage(mContext.getPackageName());
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    mContext.startActivity(intent);
    // SystemClock.sleep(3000);
    } catch (Exception e) {
    e.printStackTrace();
    }

    return true;
    }

    /**
    * 收集设备参数信息
    *
    * @param ctx
    */
    public void collectDeviceInfo(Context ctx) {
    try {
    PackageManager pm = ctx.getPackageManager();
    PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(),
    PackageManager.GET_ACTIVITIES);
    if (pi != null) {
    String versionName = pi.versionName + "";
    String versionCode = pi.versionCode + "";
    infos.put("versionName", versionName);
    infos.put("versionCode", versionCode);
    }
    } catch (NameNotFoundException e) {
    Log.e(TAG, "an error occured when collect package info", e);
    }
    Field[] fields = Build.class.getDeclaredFields();
    for (Field field : fields) {
    try {
    field.setAccessible(true);
    infos.put(field.getName(), field.get(null).toString());
    } catch (Exception e) {
    Log.e(TAG, "an error occured when collect crash info", e);
    }
    }
    }

    /**
    * 保存错误信息到文件中
    *
    * @param ex
    * @return 返回文件名称, 便于将文件传送到服务器
    * @throws Exception
    */
    private String saveCrashInfoFile(Throwable ex) throws Exception {
    StringBuffer sb = new StringBuffer();
    try {
    SimpleDateFormat sDateFormat = new SimpleDateFormat(
    "yyyy-MM-dd HH:mm:ss");
    String date = sDateFormat.format(new java.util.Date());
    sb.append(" " + date + " ");
    for (Map.Entry<String, String> entry : infos.entrySet()) {
    String key = entry.getKey();
    String value = entry.getValue();
    sb.append(key + "=" + value + " ");
    }

    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);

    String fileName = writeFile(sb.toString());
    return fileName;
    } catch (Exception e) {
    Log.e(TAG, "an error occured while writing file...", e);
    sb.append("an error occured while writing file... ");
    writeFile(sb.toString());
    }
    return null;
    }

    private String writeFile(String sb) throws Exception {
    String time = formatter.format(new Date());
    // String fileName = "partylive-" + time + ".log";
    String fileName = "partylive-" + time + ".txt";
    if (hasSdcard()) {
    String path = getGlobalpath();
    File dir = new File(path);
    if (!dir.exists())
    dir.mkdirs();

    FileOutputStream fos = new FileOutputStream(path + fileName, true);
    fos.write(sb.getBytes());
    fos.flush();
    fos.close();
    }
    return fileName;
    }

    public static String getGlobalpath() {
    return Environment.getExternalStorageDirectory().getAbsolutePath()
    + File.separator + "partylive" + File.separator;
    }

    public static void setTag(String tag) {
    TAG = tag;
    }

    /**
    * 判断SD卡是否可用
    *
    * @return SD卡可用返回true
    */
    public static boolean hasSdcard() {
    String status = Environment.getExternalStorageState();
    return Environment.MEDIA_MOUNTED.equals(status);
    }
    }
    
    
  • 相关阅读:
    vue 中引用echarts 初始化init undefind问题(Cannot read property ‘init‘ of undefined)
    粘性定位(position:sticky)实现固定表格表头、固定列
    js替换字符串中的空格,换行符 或 替换成<br>
    一个完整的大作业
    数据结构化与保存
    爬取所有校园新闻
    用requests库和BeautifulSoup4库爬取新闻列表
    中文词频统计及词云制作
    组合数据类型练习,英文词频统计实例
    字符串操作练习:星座、凯撒密码、99乘法表、词频统计预处理
  • 原文地址:https://www.cnblogs.com/huihuizhang/p/6653128.html
Copyright © 2020-2023  润新知