博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
简便地Android崩溃日志收集
阅读量:6807 次
发布时间:2019-06-26

本文共 5499 字,大约阅读时间需要 18 分钟。

对于已经发布出去的程序,一旦出现崩溃,就很难调查原因。收集崩溃日志就尤为重要。

像是腾讯Bugly就是提供类似的服务,但是我觉得这样一个很精简的功能没有必要再引入别家的服务了。

网上有很多类似功能的代码,在程序崩溃的时候把日志写入到本地文件。

我这里分享一个kotlin版本:

/** * Created by GreendaMi on 2018/5/3. */class CrashHandler :Thread.UncaughtExceptionHandler {
lateinit var mDefaultHandler: Thread.UncaughtExceptionHandler lateinit var mContext: Context // 保存手机信息和异常信息 private val mMessage = HashMap
() companion object { var sInstance: CrashHandler? = null fun getInstance(): CrashHandler? { if (sInstance == null) { synchronized(CrashHandler::class.java) { if (sInstance == null) { synchronized(CrashHandler::class.java) { sInstance = CrashHandler() } } } } return sInstance } } override fun uncaughtException(t: Thread?, e: Throwable?) { if (!handleException(e)) { // 未经过人为处理,则调用系统默认处理异常,弹出系统强制关闭的对话框 if (mDefaultHandler != null) { mDefaultHandler.uncaughtException(t, e) } } else { // 已经人为处理,系统自己退出 try { Thread.sleep(1000) } catch (e1: InterruptedException) { e1.printStackTrace() } //重启 var intent = mContext?.packageManager?.getLaunchIntentForPackage(mContext?.packageName) intent?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) mContext?.startActivity(intent) android.os.Process.killProcess(android.os.Process.myPid()) } } /** * 初始化默认异常捕获 * * @param context context */ fun init(context: Context) { mContext = context // 获取默认异常处理器 mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler() // 将此类设为默认异常处理器 Thread.setDefaultUncaughtExceptionHandler(this) } /** * 是否人为捕获异常 * * @param e Throwable * @return true:已处理 false:未处理 */ private fun handleException(e: Throwable?): Boolean { if (e == null) {
// 异常是否为空 return false } object : Thread() { // 在主线程中弹出提示 override fun run() { Looper.prepare() Toast.makeText(mContext, "程序发生未知异常,将重启。", Toast.LENGTH_SHORT).show() Looper.loop() } }.start() collectErrorMessages() saveErrorMessages(e) return false } private fun collectErrorMessages() { val pm = mContext?.packageManager try { val pi = pm?.getPackageInfo(mContext?.packageName, PackageManager.GET_ACTIVITIES) if (pi != null) { val versionName = if (TextUtils.isEmpty(pi.versionName)) "null" else pi.versionName val versionCode = "" + pi.versionCode mMessage["versionName"] = versionName mMessage["versionCode"] = versionCode } // 通过反射拿到错误信息 val fields = Build::class.java!!.fields if (fields != null && fields.isNotEmpty()) { for (field in fields!!) { field.isAccessible = true try { mMessage[field.name] = field.get(null).toString() } catch (e: IllegalAccessException) { e.printStackTrace() } } } } catch (e: PackageManager.NameNotFoundException) { e.printStackTrace() } } private fun saveErrorMessages(e: Throwable) { val sb = StringBuilder() for (entry in mMessage) { val key = entry.key val value = entry.value sb.append(key).append("=").append(value).append("\n") } val writer = StringWriter() val pw = PrintWriter(writer) e.printStackTrace(pw) var cause: Throwable? = e.cause // 循环取出Cause if (cause != null) { cause.printStackTrace(pw) } pw.close() val result = writer.toString() sb.append(result) val time = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA).format(Date()) val fileName = "crash-" + time + "-" + System.currentTimeMillis() + ".log" // 有无SD卡 if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) { val path = AppConfig.crashPath val dir = File(path) if (!dir.exists()) dir.mkdirs() var fos: FileOutputStream? = null try { fos = FileOutputStream(path + fileName) fos!!.write(sb.toString().toByteArray()) } catch (e1: Exception) { e1.printStackTrace() } finally { if (fos != null) { try { fos!!.close() } catch (e1: IOException) { e1.printStackTrace() } } } } }}复制代码

在Application里面初始化一下:

//异常收集CrashHandler.getInstance()?.init(this@App)复制代码

温馨提示:这里的写入文件都是同步的,如果需要将错误日志信息上传到服务器,因为一般这种网络通讯都是异步的,所以需要将

if (!handleException(e)) {            // 未经过人为处理,则调用系统默认处理异常,弹出系统强制关闭的对话框            if (mDefaultHandler != null) {                mDefaultHandler.uncaughtException(t, e)            }        }复制代码

中的

if (mDefaultHandler != null) {                mDefaultHandler.uncaughtException(t, e)            }复制代码

部分移动到上传结束动作的回调中,防止上传动作还没有结束,程序就被意外终止。

转载地址:http://cetwl.baihongyu.com/

你可能感兴趣的文章
解决/usr/bin/ld: cannot find -lxxx 问题
查看>>
Linux面试题
查看>>
java 内存设置
查看>>
功能表单之智能选择字段类型的使用——JEPLUS软件快速开发平台
查看>>
ios 8 适配须知
查看>>
Windows Phone 模拟器安装使用详解
查看>>
第三节:python 交互和调用参数
查看>>
linux SNAT、DNAT目标函数
查看>>
Join()--用法
查看>>
我的友情链接
查看>>
实体类转换为XML字符串
查看>>
进制转换
查看>>
ubuntu 18.04安装搜狗输入法
查看>>
我的友情链接
查看>>
apache中文翻译
查看>>
挨踢部落故事汇(2):机缘所致转型之路
查看>>
larave 5 could not be opened: failed to open stream: Permission denied
查看>>
How to Create and Drop database in MongoDB
查看>>
android基础
查看>>
win下的一款自动远程备份工具
查看>>