Android实现自定义Crash handler记录崩溃信息实例代码

 更新时间:2018年02月25日 11:42:21   作者:Rust Fisher  
这篇文章主要给大家介绍了Android实现自定义Crash handler记录崩溃信息的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。

前言

在使用自己开发的android应用时,偶尔会出现 系统已停止运行 错误.这时候如果能记录错误日志,是非常有帮助的。

App异常崩溃信息存入文件中。

应用崩溃时,尽可能的收集多的数据,方便后续定位追踪修改。

如果可以,尽量将崩溃日志上传到服务器。一些集成服务已经提供了相应的功能。

主要使用的方法是Thread.UncaughtExceptionHandler

方法如下

一般在application中启动CrashHandler,个人认为应该放在调用其他模块前尽早启动。

CrashHandler.java

import android.os.Build;
import android.os.Environment;
import android.os.Process;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class CrashHandler implements Thread.UncaughtExceptionHandler {
 private static final String TAG = "CrashHandler";
 private static final boolean DEBUG = true;
 // 自定义存储的目录
 private static final String PATH = Environment.getExternalStorageDirectory().getPath() + "/myApp/log/";
 private static final String FILE_NAME = "crash";
 private static final String FILE_NAME_SUFFIX = ".txt";
 private String phoneInfo;
 private static CrashHandler instance = new CrashHandler();
 private Thread.UncaughtExceptionHandler mDefaultCrashHandler;

 private CrashHandler() {
 }

 public static CrashHandler getInstance() {
  return instance;
 }

 public void init() {
  mDefaultCrashHandler = Thread.getDefaultUncaughtExceptionHandler();
  Thread.setDefaultUncaughtExceptionHandler(this);
  phoneInfo = getPhoneInformation();
 }

 /**
  * 这个是最关键的函数,当程序中有未被捕获的异常,系统将会自动调用uncaughtException方法
  * thread为出现未捕获异常的线程,ex为未捕获的异常,有了这个ex,我们就可以得到异常信息
  */
 @Override
 public void uncaughtException(Thread thread, Throwable ex) {
  try {
   //导出异常信息到SD卡中
   dumpExceptionToSDCard(ex);
   //这里可以上传异常信息到服务器,便于开发人员分析日志从而解决bug
   uploadExceptionToServer();
  } catch (IOException e) {
   e.printStackTrace();
  }
  ex.printStackTrace();
  //如果系统提供默认的异常处理器,则交给系统去结束程序,否则就由自己结束自己
  if (mDefaultCrashHandler != null) {
   mDefaultCrashHandler.uncaughtException(thread, ex);
  } else {
   try {
    Thread.sleep(2000); // 延迟2秒杀进程
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   android.os.Process.killProcess(Process.myPid());
  }
 }

 private void dumpExceptionToSDCard(Throwable ex) throws IOException {
  //如果SD卡不存在或无法使用,则无法把异常信息写入SD卡
  if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
   if (DEBUG) {
    Log.e(TAG, "sdcard unmounted,skip dump exception");
    return;
   }
  }
  File dir = new File(PATH);
  if (!dir.exists()) {
   dir.mkdirs();
  }
  long current = System.currentTimeMillis();
  String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA).format(new Date(current));
  File file = new File(PATH + FILE_NAME + time + FILE_NAME_SUFFIX);
  try {
   PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(file)));
   pw.println(time);
   pw.println(phoneInfo);
   pw.println();
   ex.printStackTrace(pw);
   pw.close();
   Log.e(TAG, "dump crash info seccess");
  } catch (Exception e) {
   Log.e(TAG, e.getMessage());
   Log.e(TAG, "dump crash info failed");
  }
 }

 private void uploadExceptionToServer() {
  // 将异常信息发送到服务器
 }

 private String getPhoneInformation() {
  StringBuilder sb = new StringBuilder();
  sb.append("App version name:")
    .append(BuildConfig.VERSION_NAME)
    .append(", version code:")
    .append(BuildConfig.VERSION_CODE).append("\n");
  //Android版本号
  sb.append("OS Version: ");
  sb.append(Build.VERSION.RELEASE);
  sb.append("_");
  sb.append(Build.VERSION.SDK_INT).append("\n");
  //手机制造商
  sb.append("Vendor: ");
  sb.append(Build.MANUFACTURER).append("\n");
  //手机型号
  sb.append("Model: ");
  sb.append(Build.MODEL).append("\n");
  //CPU架构
  sb.append("CPU ABI:").append("\n");
  for (String abi : Build.SUPPORTED_ABIS) {
   sb.append(abi).append("\n");
  }
  return sb.toString();
 }
}

使用方式,可在Application中调用初始化方法

@Override
public void onCreate() {
 super.onCreate();
 // init application...
 CrashHandler.getInstance().init();
}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

相关文章

  • android panellistview 圆角实现代码

    android panellistview 圆角实现代码

    android panellistview 圆角是每一个android开发者都具备的一项,对于新手朋友来说可能有点难度,接下来将详细介绍,需要了解的朋友可以参考下
    2012-12-12
  • Android中Bitmap用法实例分析

    Android中Bitmap用法实例分析

    这篇文章主要介绍了Android中Bitmap用法,结合实例形式分析了Android操作图片的载入、属性设置、旋转等相关技巧,需要的朋友可以参考下
    2016-02-02
  • 详解Android的网络数据存储

    详解Android的网络数据存储

    LeanCloud是一种简单高效的数据和文件存储服务,本文主要介绍了利用LeanCloud来进行网络数据的存储的实现方法。具有很好的参考价值,需要的朋友一起来看下吧
    2016-12-12
  • android webview中使用Java调用JavaScript方法并获取返回值

    android webview中使用Java调用JavaScript方法并获取返回值

    这篇文章主要介绍了android webview中使用Java调用JavaScript方法并获取返回值,本文直接给出代码示例,需要的朋友可以参考下
    2015-03-03
  • android车牌识别系统EasyPR使用详解

    android车牌识别系统EasyPR使用详解

    这篇文章主要为大家详细介绍了android车牌识别系统EasyPR使用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-12-12
  • Android编程实现动画自动播放功能

    Android编程实现动画自动播放功能

    这篇文章主要介绍了Android编程实现动画自动播放功能,结合实例形式分析了Android动画自动播放功能的实现方法与相关注意事项,需要的朋友可以参考下
    2017-07-07
  • Android接入USB扫码模块的方法

    Android接入USB扫码模块的方法

    这篇文章主要为大家详细介绍了Android接入USB扫码模块的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • Android录音应用实例教程

    Android录音应用实例教程

    这篇文章主要介绍了Android录音应用实例,是Android应用程序开发中非常重要的一个功能,需要的朋友可以参考下
    2014-09-09
  • Android 开发之dataBinding与ListView及事件

    Android 开发之dataBinding与ListView及事件

    这篇文章主要介绍了Android 开发之dataBinding与ListView及事件的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-10-10
  • Android实现淘宝倒计时功能

    Android实现淘宝倒计时功能

    这篇文章主要为大家详细介绍了Android实现淘宝倒计时,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02

最新评论