Android崩潰日志收集和保存解析
面試
記得很久很久以前的一次面試中被面試官問(wèn):
面試官:你的崩潰日志是怎么收集的?
我答:集成騰訊的Bugly收集。
面試官:如果不用第三方呢?
我:好像有個(gè)什么異常的handler,具體想不起來(lái)了
那么今天我們就來(lái)聊聊關(guān)于崩了日志收集的以上兩種方式UncaughtExceptionHandler和Bugly
UncaughtExceptionHandler
- UncaughtExceptionHandler UncaughtExceptionHandler類(lèi)是java1.5里新增的Thread類(lèi)里面的一個(gè)函數(shù)式接口類(lèi)的,接口處理器時(shí)調(diào)用線程突然終止,由于未捕獲到異常。當(dāng)一個(gè)線程要終止由于未捕獲到異常的Java虛擬機(jī)將查詢線程其使用的UncaughtExceptionHandler.getUncaughtExceptionHandler,將調(diào)用處理程序的uncaughtException方法,將線程和異常作為參數(shù)。
首先我們需要編寫(xiě)該接口實(shí)現(xiàn)類(lèi),重寫(xiě)uncaughtException方法,一旦應(yīng)用發(fā)生異常該方法就會(huì)觸發(fā),所以我們的業(yè)務(wù)邏輯就必須在這個(gè)接口中實(shí)現(xiàn)。
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() ...... }
通過(guò)入?yún)tringWriter的PrintWriter獲取到Throwable信息,再將StringWriter的信息打印出來(lái)就是應(yīng)用的崩潰信息,獲取過(guò)程雖稍顯復(fù)雜但使用還是極其簡(jiǎn)單。之后就是將日志保存在本地和上傳服務(wù)器的過(guò)程了。
val fos = FileOutputStream(path + fileName) fos.write(sb.toString().toByteArray())
既然有儲(chǔ)存那么就一定要有刪除功能,否則一旦數(shù)據(jù)量大了后手機(jī)內(nèi)存就不夠用了,我們?cè)O(shè)置一個(gè)清除15天前數(shù)據(jù)。
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)//截取時(shí)間戳 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() } } } } } }
最后,當(dāng)然是需要初始化這個(gè)工具類(lèi),盡可能在應(yīng)用啟動(dòng)時(shí)初始化。
override fun onCreate() { super.onCreate() CrashHandler.instance.init(this) }
如需保存到服務(wù)器則保存本地的同時(shí)即可保存到服務(wù)器。這里分享一個(gè)當(dāng)時(shí)遇到的問(wèn)題,debug和realase兩個(gè)版本中一個(gè)可以在保存目錄找到日志,一個(gè)根本找不到該目錄。經(jīng)過(guò)反復(fù)對(duì)比和查找資料才發(fā)現(xiàn),原來(lái)是cacheDir和externalCacheDir的區(qū)別,哈哈哈,著實(shí)給我整懵逼了。
Bugly
為移動(dòng)開(kāi)發(fā)者提供專(zhuān)業(yè)的異常上報(bào)和運(yùn)營(yíng)統(tǒng)計(jì),幫助開(kāi)發(fā)者快速發(fā)現(xiàn)并解決異常,同時(shí)掌握產(chǎn)品運(yùn)營(yíng)動(dòng)態(tài),及時(shí)跟進(jìn)用戶反饋。
Bugly是一款免費(fèi)的三方庫(kù),提供崩潰日志和應(yīng)用更新、運(yùn)營(yíng)統(tǒng)計(jì)等功能,去年應(yīng)用更新功能(全量更新)被割掉了,非常遺憾,但崩潰日志還能正常使用并且做的也很不錯(cuò)。相當(dāng)于它提供后臺(tái)存儲(chǔ),對(duì)于一些NDK之類(lèi)的底層報(bào)錯(cuò)和代碼混淆可以通過(guò)上傳符號(hào)表查看報(bào)錯(cuò)信息。
在build.gradle文件中添加配置和依賴
android { defaultConfig { // 設(shè)置支持的SO庫(kù)架構(gòu) abiFilters 'armeabi' //, 'x86', 'armeabi-v7a', 'x86_64', ndk { 'arm64-v8a' } } } //其中l(wèi)atest.release指代最新Bugly SDK版本號(hào),也可以指定明確的版本號(hào),例如4.0.3 } dependencies { implementation 'com.tencent.bugly:crashreport:latest.release'
盡可能早的初始化
CrashReport.initCrashReport(getApplicationContext(), "注冊(cè)時(shí)申請(qǐng)的APPID", false);
之后出現(xiàn)應(yīng)用異常即可在賬號(hào)內(nèi)查看和處理,可以說(shuō)功能還是比較齊全的。
總結(jié)
其實(shí)現(xiàn)在網(wǎng)上很多關(guān)于崩潰日志的庫(kù),啥蒲公英、加固類(lèi)Sdk都有,最終還是得根據(jù)項(xiàng)目情況選擇一款條件合適得工具。UncaughtExceptionHandler使用也簡(jiǎn)單,但需要開(kāi)發(fā)者自己使用代碼做好日志整理、收集、上傳功能,如果涉及上傳就得需要后端配合,無(wú)疑又增加了人員維護(hù),好處就是自己服務(wù)器控制數(shù)據(jù)。三方庫(kù)使用就更簡(jiǎn)單了,連后端都省了,但因此也帶來(lái)了弊端,始終數(shù)據(jù)在別人服務(wù)器中,這個(gè)不可控,如涉及隱私可能也不會(huì)選擇它。
以上就是Android崩潰日志收集和保存解析的詳細(xì)內(nèi)容,更多關(guān)于Android崩潰日志收集保存的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android高效加載大圖、多圖解決方案 有效避免程序OOM
這篇文章主要為大家詳細(xì)介紹了Android高效加載大圖、多圖解決方案,有效避免程序OOM,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10Android 重寫(xiě)ViewGroup 分析onMeasure()和onLayout()方法
這篇文章主要介紹了Android 重寫(xiě)ViewGroup 分析onMeasure()和onLayout()方法的相關(guān)資料,需要的朋友可以參考下2017-06-06Android AIDL中Map參數(shù)傳遞的問(wèn)題詳解
這篇文章主要給大家介紹了關(guān)于Android AIDL中Map參數(shù)傳遞問(wèn)題的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友下面來(lái)一起看看吧。2017-12-12Android把svg圖片轉(zhuǎn)為jpg保存到相冊(cè)圖庫(kù)
這篇文章主要為大家詳細(xì)介紹了Android把svg圖片轉(zhuǎn)為jpg保存到相冊(cè)圖庫(kù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05Android實(shí)現(xiàn)氣泡布局/彈窗效果 氣泡尖角方向及偏移量可控
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)氣泡布局/彈窗效果,可控制氣泡尖角方向及偏移量,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-08-08多面分析HarmonyOS與Android的特點(diǎn)
請(qǐng)教身邊的大佬們,公司的CTO、中臺(tái)部門(mén)的總監(jiān)、老東家數(shù)十年行業(yè)經(jīng)驗(yàn)的老架構(gòu)、以及在中科院讀研究生的大學(xué)老室友、技術(shù)圈的網(wǎng)友等等,他們都給出了自己獨(dú)特的看法,讓我從多方面更好的去了解到了大家對(duì)鴻蒙的認(rèn)識(shí)2021-08-08Android Studio 通過(guò)登錄功能介紹SQLite數(shù)據(jù)庫(kù)的使用流程
SQLite是一款輕型的數(shù)據(jù)庫(kù),是遵守ACID的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),它包含在一個(gè)相對(duì)小的C庫(kù)中。這篇文章主要介紹了Android Studio 通過(guò)登錄功能介紹SQLite數(shù)據(jù)庫(kù)的使用流程,需要的朋友可以參考下2018-09-09Android SurfaceView基礎(chǔ)用法詳解
這篇文章主要介紹了Android SurfaceView基礎(chǔ)用法詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08Android學(xué)習(xí)筆記——Menu介紹(二)
這次將繼續(xù)上一篇文章沒(méi)有講完的Menu的學(xué)習(xí),上下文菜單(Context menu)和彈出菜單(Popup menu)2014-10-10