如何将应用崩溃日志收集起来?

Android 应用难以避免的会 crash ,也称为崩溃,无论你的程序多完美,总是无法避免 crash 的发生。这对用户来说是很不友好的,也是开发者所不愿意看到的。更糟糕的是,当用户发生了 crash ,开发者却不知道程序为何 crash,即使开发者想去解决这个 crash 也由于不知道用户当时的 crash 信息,所以往往也无能为力。这篇博客,便教大家怎样获取到应用的崩溃日志并且上传。(本篇博客部分素材取自开发艺术探索)

下面就开始吧

Android 系统提供了处理这类问题的方法,Thread 类中提供了一个方法 setDefaultUncaughtExceptionHandler

    /*** Set the default handler invoked when a thread abruptly terminates* due to an uncaught exception, and no other handler has been defined* for that thread.* * @param eh the object to use as the default uncaught exception handler.* If <tt>null</tt> then there is no default handler.* /public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {defaultUncaughtExceptionHandler = eh;}

这个方法可以设置系统的默认异常处理器,这个方法就可以解决上面所提的 crash 问题,当 crash 发生的时候,系统就会回调 UncaughtExceptionHandler 的 uncaughtException 方法,在 uncaughtException 方法中可以获取到异常信息,可以选择把异常信息存储到 SD卡中*,然后在合适的时机通过网络将 crash 信息上传到服务器上,这样开发人员就可以分析用户 crash 的场景,从而在后面的版本修复此类 crash 了。

经过上面的分析,我们就有思路了。首先,我们需要实现一个 UncaughtExceptionHandler 对象,在它的 uncaughtException 方法中获取异常信息并将其存入 SD卡中或者上传到服务器上,然后调用 Thread 的 setDefultUncaughtExceptionHandler 方法将它设置为线程默认的异常处理器。说到这里,可别蒙圈,下面直接上代码:


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.util.Log;import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.Thread.UncaughtExceptionHandler;
import java.text.SimpleDateFormat;
import java.util.Date;/*** Create by ChenHao on 2018/6/299:30* use : 应用异常处理类* 使用方式: 在Application 中初始化  CrashHandler.getInstance().init(this);*/
public class CrashHandler implements UncaughtExceptionHandler {private static final String TAG = "CrashHandler";public static final boolean DEBUG = true;/*** 文件名*/public static final String FILE_NAME = "crash";/*** 异常日志 存储位置为根目录下的 Crash文件夹*/private static final String PATH = Environment.getExternalStorageDirectory().getPath() +"/Crash/log/";/*** 文件名后缀*/private static final String FILE_NAME_SUFFIX = ".trace";private static CrashHandler sInstance = new CrashHandler();private UncaughtExceptionHandler mDefaultCrashHandler;private Context mContext;private CrashHandler() {}public static CrashHandler getInstance() {return sInstance;}/*** 初始化** @param context*/private void init(Context context) {//得到系统的应用异常处理器mDefaultCrashHandler = Thread.getDefaultUncaughtExceptionHandler();//将当前应用异常处理器改为默认的Thread.setDefaultUncaughtExceptionHandler(this);mContext = context.getApplicationContext();}/*** 这个是最关键的函数,当系统中有未被捕获的异常,系统将会自动调用 uncaughtException 方法** @param thread 为出现未捕获异常的线程* @param ex     为未捕获的异常 ,可以通过e 拿到异常信息*/@Overridepublic void uncaughtException(Thread thread, Throwable ex) {//导入异常信息到SD卡中try {dumpExceptionToSDCard(ex);} catch (IOException e) {e.printStackTrace();}//这里可以上传异常信息到服务器,便于开发人员分析日志从而解决BuguploadExceptionToServer();ex.printStackTrace();//如果系统提供了默认的异常处理器,则交给系统去结束程序,否则就由自己结束自己if (mDefaultCrashHandler != null) {mDefaultCrashHandler.uncaughtException(thread, ex);} else {Process.killProcess(Process.myPid());}}/*** 将异常信息写入SD卡** @param e*/private void dumpExceptionToSDCard(Throwable e) throws IOException{//如果SD卡不存在或无法使用,则无法将异常信息写入SD卡if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {if (DEBUG) {Log.w(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").format(new Date(current));//在定义的Crash文件夹下创建文件File file = new File(PATH + FILE_NAME + time + FILE_NAME_SUFFIX);try{PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(file)));//写入时间pw.println(time);//写入手机信息dumpPhoneInfo(pw);pw.println();//换行e.printStackTrace(pw);pw.close();//关闭输入流} catch (Exception e1) {Log.e(TAG,"dump crash info failed");}}/*** 获取手机各项信息* @param pw*/private void dumpPhoneInfo(PrintWriter pw) throws PackageManager.NameNotFoundException {//得到包管理器PackageManager pm = mContext.getPackageManager();//得到包对象PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(),PackageManager.GET_ACTIVITIES);//写入APP版本号pw.print("App Version: ");pw.print(pi.versionName);pw.print("_");pw.println(pi.versionCode);//写入 Android 版本号pw.print("OS Version: ");pw.print(Build.VERSION.RELEASE);pw.print("_");pw.println(Build.VERSION.SDK_INT);//手机制造商pw.print("Vendor: ");pw.println(Build.MANUFACTURER);//手机型号pw.print("Model: ");pw.println(Build.MODEL);//CPU架构pw.print("CPU ABI: ");if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {pw.println(Build.SUPPORTED_ABIS);}else {pw.println(Build.CPU_ABI);}}/*** 将错误信息上传至服务器*/private void uploadExceptionToServer() {}
}

大家可以在 uploadExceptionToServer 方法中写上自己上传服务器的逻辑,最后的最后,别忘了在 application 中初始化我们的异常处理器。

 CrashHandler.getInstance().init(this);

博客到这里就结束了,点个赞吧。

Android 应用崩溃日志的收集和上传相关推荐

  1. Android 异常崩溃日志,捕捉并保存到本地

    Android 异常崩溃日志,捕捉并保存到本地: 前几天因为在省公安厅做一个通讯类之类的应用:碰到个问题,就是download人员信息将信息保存到本地数据库完成的时候,菊花转还没有dismission ...

  2. Android捕捉崩溃日志并输出日志文件

    Android捕捉崩溃日志并输出日志文件 当程序与运行时发生崩溃,可以捕捉到当前崩溃的日志信息并写入文件保存到指定的目录下.这里还做了最大文件数量限制,超过数量即删除旧日志文件. import jav ...

  3. java 崩溃日志_Android收集程序崩溃日志的方法

    安卓Android如何手机程序崩溃日志并上传到服务器呢?直接会用到Thread线程里面的UncaughtExceptionHandler接口方法,我们可以自定义一个类CrashHandler,代码如下 ...

  4. Android网络功能开发(4)——文件下载和上传

    本篇介绍使用HTTP协议实现文件下载和上传.在客户端和服务器的通信过程中,可能有些多媒体或数据文件需要下载或上传,可以通过HTTP协议实现. 首先看使用HTTP协议下载文件的原理:客户端发送一个HTT ...

  5. android查找邮件程序,Android 程序崩溃日志邮件获取

    版权声明:本文为博主原创文章,未经博主允许不得转载. 在我们开发Android应用程序的时候,BUG的出现是难以避免的,时不时还会出现崩溃的情况,这个时候,我们急需知道造成问题的原因是什么,但是,在没 ...

  6. Android 保存崩溃日志到本地目录下

    代码如下可以直接复制过去,别人的代码修改了下 package com.hly.rtxt; import android.annotation.SuppressLint; import android. ...

  7. android 记录崩溃日志

    2019独角兽企业重金招聘Python工程师标准>>> 每个android应用都是由一个Application和多个activity或者server构成.应用启动时,会首先启动App ...

  8. android xlog崩溃日志,腾讯Xlog接入指南与踩过的坑

    一 为什么要接入日志打印系统? 相信大家在开发应用的时候,总会遇到bug,这个时候,如果bug是在我们本地开发的过程中发现的,那么我们把手机插入android studio进行联调,就可以马上定位到出 ...

  9. android xlog崩溃日志,Android第三方log库:xlog使用记录

    第一步:由于xlog发布在jitpack 仓库,所以如果android studio没有在project目下的的build.gradle下配置jitpack仓库的话需要配置下 allprojects ...

最新文章

  1. 博士补贴125万,硕士70万本科21万,浙江某地人才(简直是抢人)新政!
  2. 多线程:多线程优缺点、应用场景
  3. boost::mp11::mp_sort_q相关用法的测试程序
  4. android shape 按钮背景_Android button, xml文件定义形状,代码中修改背景颜色
  5. 递归javascript_使用freeCodeCamp挑战解释了JavaScript中的递归
  6. 揭秘5位爬藤“牛娃” 他们吸引藤校的到底是什么?
  7. 快手公司厕所装坑位计时器,网友:再也不能带薪拉屎了!
  8. qt-sdk-linux,在linux系统上安装qt-sdk步骤.doc
  9. ubuntu 16.04 和win10双系统ubuntu无法更新问题解决
  10. Excel-VBA 快速上手(一、宏、VBA、过程、类型与变量、函数)
  11. 用HTML搞一个汇率转换器,利用yahoo汇率接口实现实时汇率转换示例 汇率转换器...
  12. 【Multisim仿真】利用运算放大器产生方波、三角波发生器
  13. UE4拾色器的实现,使用UE4自带的SColorPicker
  14. 关于手机输入法的一些点子
  15. 5611AH 数码管 引脚图
  16. docker 入门 —— docker 镜像命令
  17. PhotoShop下载选择路径
  18. 音视频开发---M3U8 https://www.jianshu.com/p/e97f6555a070
  19. 易经八卦原理图谱和记忆方法总结
  20. 台湾TST嘉硕晶体晶振SAW滤波器的介绍和在电路中的应用

热门文章

  1. “sample”, “batch”, “epoch” 分别是什么?
  2. Android Aidl 爱之初体验?
  3. pytorch中nn.Conv2d卷积的padding的取值问题
  4. 谷歌地球无法连接_为什么最有价值的商业活动是“建立连接”?
  5. Java开发环境!杭州java开发应届生工资
  6. 名下淘宝店铺严重违规无法开店怎么办?技术公开
  7. 喜欢听着歌写代码的福利(vscode插件)
  8. 飞鸽传书——呼叫系统
  9. 三、2.游戏商城模块的详细设计
  10. 计算机教室是在音乐教室旁边吗英语,小学英语四年级下册Unit1教材同步音频+释义...