zoukankan      html  css  js  c++  java
  • android 捕获未try的异常、抓取崩溃日志

    1.Thread.UncaughtExceptionHandler

      java里有很多异常如:空指针异常,越界异常,数值转换异常,除0异常,数据库异常等等。如果自己没有try / catch 那么线程就崩溃。

      并不能对所有代码都try/catch,如果代码产生了未捕获的异常,又不想让程序崩溃,或者在崩溃之前要做一些收尾工作。怎么办?

      Thread.UncaughtExceptionHandler 类可以解决这个问题,当有未捕获异常时,它的 public void uncaughtException(Thread t, Throwable e) 方法会被调用,参数包含了崩溃的线程及相应的异常信息。

      Thread类中的 public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) 方法指定接收未捕获异常处理类。通常在 Application 里指定一个生命周期很长的未捕获异常处理类。

    2.示例

    2.1 自定义Thread.UncaughtExceptionHandler

     1 import android.content.Context
     2 import android.content.pm.PackageManager
     3 import android.os.Build
     4 import java.io.File
     5 import java.io.PrintWriter
     6 import java.text.SimpleDateFormat
     7 import java.util.*
     8 
     9 class CrashHandler(val context: Context) : Thread.UncaughtExceptionHandler {
    10 
    11     private lateinit var default : Thread.UncaughtExceptionHandler
    12     override fun uncaughtException(t: Thread, e: Throwable) {
    13         e.printStackTrace()
    14         writeLog(t,e)
    15         if (::default.isInitialized){
    16             default.uncaughtException(t,e)
    17         }
    18     }
    19 
    20     fun start(){
    21         default = Thread.getDefaultUncaughtExceptionHandler()
    22         Thread.setDefaultUncaughtExceptionHandler(this)
    23     }
    24 
    25     fun writeLog(t: Thread, e: Throwable){
    26         val log = context.getExternalFilesDir("")?.absolutePath + "/crash.log"
    27         val time = SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())
    28         try {
    29             val file = File(log)
    30             val pw = PrintWriter(file,"UTF-8")
    31             pw.println("time        : $time")
    32             pw.println("Thread      : name = ${t.name} ,priority = ${t.priority} , pid = ${t.id}")
    33             writePhoneInfo(pw)
    34             e.printStackTrace(pw)
    35             pw.close()
    36         }catch (e : Exception){
    37             e.printStackTrace()
    38         }
    39     }
    40     fun writePhoneInfo(pw : PrintWriter) {
    41         val pm = context.getPackageManager()
    42         val pi = pm.getPackageInfo(context.packageName,PackageManager.GET_ACTIVITIES)
    43 
    44         pw.println("app version : ${pi.versionName}")
    45         pw.println("android ver : ${Build.VERSION.RELEASE}")
    46         pw.println("sdk version : ${Build.VERSION.SDK_INT}")
    47         pw.println("product     : ${Build.PRODUCT}")
    48 
    49         pw.println("vendor      : ${Build.MANUFACTURER}")
    50         pw.println("brand       : ${Build.BRAND}")
    51         pw.println("model       : ${Build.MODEL}")
    52         pw.println("hardware    : ${Build.HARDWARE}")
    53 
    54 
    55         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    56             var abis = ""
    57             for (abi in Build.SUPPORTED_ABIS){
    58                 abis += "$abi,"
    59             }
    60             pw.println("CPU_abis    : ${abis}")
    61         }else{
    62             pw.println("CPU_abi     : ${Build.CPU_ABI}")
    63         }
    64     }
    65 }

    如图:

    2.2 在application里注册

    1     lateinit var crash      :   CrashHandler
    2     fun crashHandler(){
    3         crash = CrashHandler(context = applicationContext)
    4         crash.start()
    5     }

    2.3 在自定义的线程中注册

     1  private void init(){
     2 
     3         new Thread(){
     4             @Override
     5             public void run() {
     6                 setUncaughtExceptionHandler(crashHandler);
     7                 int num = 100 / 0;
     8             }
     9         }.start();
    10     }
    11     public CrashHandler crashHandler = new CrashHandler();
    12     public class CrashHandler implements Thread.UncaughtExceptionHandler {
    13         final String TAG = "CrashHandler";
    14 
    15         @Override
    16         public void uncaughtException(Thread t, Throwable e) {
    17             e.printStackTrace();
    18             Log.e(TAG, "uncaughtException: " + e.getMessage() + " thread = " + t.getId());
    19             if (t.getId() == 1){
    20                 //...
    21             }
    22             //异常信息收集
    23             //应用程序信息收集
    24             //保存错误报告文件到文件。
    25         }
    26     }
  • 相关阅读:
    洛谷P2024 [NOI2001]食物链 题解 并查集
    洛谷P1632 点的移动 题解 枚举
    洛谷P2733 家的范围 题解 动态规划
    洛谷P1432 倒水问题 题解 广搜经典入门题(SPFA求解)
    18个常用的Linux 命令
    python 基础知正则表达式
    python 多功能下载网页
    Python3 安装urllib2包之小坑
    python 爬虫需要的库
    python html简单入门
  • 原文地址:https://www.cnblogs.com/mhbs/p/10506327.html
Copyright © 2011-2022 走看看