網站首頁 編程語言 正文
面試
記得很久很久以前的一次面試中被面試官問:
面試官:你的崩潰日志是怎么收集的?
我答:集成騰訊的Bugly收集。
面試官:如果不用第三方呢?
我:好像有個什么異常的handler,具體想不起來了
那么今天我們就來聊聊關于崩了日志收集的以上兩種方式UncaughtExceptionHandler和Bugly
UncaughtExceptionHandler
- UncaughtExceptionHandler UncaughtExceptionHandler類是java1.5里新增的Thread類里面的一個函數式接口類的,接口處理器時調用線程突然終止,由于未捕獲到異常。當一個線程要終止由于未捕獲到異常的Java虛擬機將查詢線程其使用的UncaughtExceptionHandler.getUncaughtExceptionHandler,將調用處理程序的uncaughtException方法,將線程和異常作為參數。
首先我們需要編寫該接口實現類,重寫uncaughtException方法,一旦應用發生異常該方法就會觸發,所以我們的業務邏輯就必須在這個接口中實現。
override fun uncaughtException(t: Thread, e: Throwable) {
//崩潰信息
val writer = StringWriter()
val printWriter = PrintWriter(writer)
e.printStackTrace(printWriter)
var cause: Throwable? = e.cause
while (cause != null) {
cause.printStackTrace(printWriter)
cause = cause.cause
}
printWriter.close()
val result: String = writer.toString()
......
}
通過入參StringWriter的PrintWriter獲取到Throwable信息,再將StringWriter的信息打印出來就是應用的崩潰信息,獲取過程雖稍顯復雜但使用還是極其簡單。之后就是將日志保存在本地和上傳服務器的過程了。
val fos = FileOutputStream(path + fileName)
fos.write(sb.toString().toByteArray())
既然有儲存那么就一定要有刪除功能,否則一旦數據量大了后手機內存就不夠用了,我們設置一個清除15天前數據。
private fun deleteFile() {
val file = File(path)
val nowDate = Date()
if (file.exists() && file.listFiles().isNotEmpty()) {
for (item in file.listFiles()) {
if (item.isFile) {
val split = item.name.split(".")
if (split.isNotEmpty()) {
val old = split[0].substring(6, split[0].length)//截取時間戳
val oldDate = formatter.parse(old)
val diff = nowDate.time - oldDate.time
val days = diff / (1000 * 60 * 60 * 24)
val minutes = (diff % (1000 * 60 * 60)) / (1000 * 60)
if (days > 15) {
item.delete()
}
}
}
}
}
}
最后,當然是需要初始化這個工具類,盡可能在應用啟動時初始化。
override fun onCreate() {
super.onCreate()
CrashHandler.instance.init(this)
}
如需保存到服務器則保存本地的同時即可保存到服務器。這里分享一個當時遇到的問題,debug和realase兩個版本中一個可以在保存目錄找到日志,一個根本找不到該目錄。經過反復對比和查找資料才發現,原來是cacheDir和externalCacheDir的區別,哈哈哈,著實給我整懵逼了。
Bugly
Bugly
為移動開發者提供專業的異常上報和運營統計,幫助開發者快速發現并解決異常,同時掌握產品運營動態,及時跟進用戶反饋。
Bugly是一款免費的三方庫,提供崩潰日志和應用更新、運營統計等功能,去年應用更新功能(全量更新)被割掉了,非常遺憾,但崩潰日志還能正常使用并且做的也很不錯。相當于它提供后臺存儲,對于一些NDK之類的底層報錯和代碼混淆可以通過上傳符號表查看報錯信息。
在build.gradle文件中添加配置和依賴
android {
defaultConfig {
// 設置支持的SO庫架構 abiFilters 'armeabi' //, 'x86', 'armeabi-v7a', 'x86_64',
ndk {
'arm64-v8a'
}
}
}
//其中latest.release指代最新Bugly SDK版本號,也可以指定明確的版本號,例如4.0.3 }
dependencies { implementation 'com.tencent.bugly:crashreport:latest.release'
盡可能早的初始化
CrashReport.initCrashReport(getApplicationContext(), "注冊時申請的APPID", false);
之后出現應用異常即可在賬號內查看和處理,可以說功能還是比較齊全的。
總結
其實現在網上很多關于崩潰日志的庫,啥蒲公英、加固類Sdk都有,最終還是得根據項目情況選擇一款條件合適得工具。UncaughtExceptionHandler使用也簡單,但需要開發者自己使用代碼做好日志整理、收集、上傳功能,如果涉及上傳就得需要后端配合,無疑又增加了人員維護,好處就是自己服務器控制數據。三方庫使用就更簡單了,連后端都省了,但因此也帶來了弊端,始終數據在別人服務器中,這個不可控,如涉及隱私可能也不會選擇它。
原文鏈接:https://juejin.cn/post/7204471780140810295
- 上一篇:沒有了
- 下一篇:沒有了
相關推薦
- 2022-07-17 C++深入講解引用的特點及與指針的區別_C 語言
- 2022-06-20 C語言超全面define預處理指令的使用說明_C 語言
- 2022-03-29 Qt超時鎖屏的實現示例_C 語言
- 2024-07-13 Springboot使用注解實現權限校驗
- 2022-04-22 Golang執行流程詳解,兩種執行流程方式有什么不同
- 2022-07-13 @postconstruct注解 和 InitializingBean 在bean實例化后執行某些初
- 2024-04-07 Linux如何查看當前占用CPU和內存最多的進程
- 2022-07-19 在 NgModule 里通過依賴注入的方式注冊服務實例
- 欄目分類
-
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支