安卓穩定性之crash詳解

目錄

  • 前言
  • 一、Crash 的基本原理
  • 二、Crash 分析思路
  • 三、實例分析
  • 四、預防措施
  • 五、參考鏈接


前言

在開發和測試 Android 應用程序時,遇到應用程序崩潰是很常見的情況。 Android 崩潰指的是應用程序因為異常或錯誤而無法正常執行,并且導致應用強制關閉。


一、Crash 的基本原理

Android 應用運行在 Dalvik/ART 虛擬機中,當應用中出現未處理的異常時,虛擬機會終止應用的進程,導致應用崩潰。通常, Android Crash 可以分為以下幾種類型:

  1. 空指針異常(NullPointerException) :當代碼嘗試訪問一個空對象引用時,會拋
    出該異常。
  2. 數組越界異常(ArrayIndexOutOfBoundsException) :當代碼嘗試訪問超過數組
    邊界范圍的元素時,會拋出該異常。
  3. 類轉換異常(ClassCastException) :當代碼嘗試將一個對象轉換成不兼容的類型
    時,會拋出該異常。
  4. 內存泄漏(Memory Leaks) :當應用程序持有對某個對象的引用,但該對象已經
    不再需要并且無法被釋放回收時,就發生了內存泄漏。
  5. 資源未釋放(Resource Not Released) :在使用一些需要手動管理資源(如數據
    庫連接、文件流等)的情況下,如果沒有正確釋放這些資源,在長時間運行后可能
    導致系統資源耗盡并觸發崩潰

二、Crash 分析思路

  1. 收集 Crash 信息
    要分析 Crash,首先需要收集相關的信息。我們可以通過以下途徑獲取 Crash 信息:
    ? Android Studio 的 Logcat
    ? 第三方 Crash 收集工具(如: Firebase Crashlytics, Bugly 等)
    ? 操作系統提供的日志工具(如: adb logcat)

  2. 分析 Crash 日志
    分析 Crash 日志是定位問題的關鍵。我們需要關注以下幾個方面的信息:
    ? 異常類型: Java 層異常、 Native 層異常或 ANR
    ? 異常原因:例如空指針異常、數組越界等
    ? 堆棧信息:從堆棧信息中,我們可以定位到具體的代碼行數

  3. 重現崩潰
    為了更好地理解問題,我們需要嘗試重現崩潰。這可以幫助我們確定崩潰發生的條件和場
    景。重現崩潰還可以幫助我們驗證解決方案是否有效。

  4. 調試和測試
    在確定崩潰原因后,我們需要進行調試和測試。這可以幫助我們驗證解決方案是否有效,
    并確保它不會引入新的問題。一般 crash 的問題比較明顯,容易找到問題。


三、實例分析

案例:空指針異常

09-22 07:16:41.848 +0000 17248 17248 D AndroidRuntime: Shutting down VM
09-22 07:16:41.848 +0000 17248 17248 E AndroidRuntime: *** FATAL EXCEPTION INSYSTEM PROCESS: main
09-22 07:16:41.848 +0000 17248 17248 E AndroidRuntime: java.lang.NullPointerException: Attempt to read from field 'java.lang.String com.android.server.pm.Settings$VersionInfo.fingerprint' on a null object reference
09-22 07:16:41.848 +0000 17248 17248 E AndroidRuntime: at com.android.server.pm.PackageManagerService.<init>(PackageManagerService.java:7613)
09-22 07:16:41.848 +0000 17248 17248 E AndroidRuntime: at com.android.server.pm.PackageManagerService.main(PackageManagerService.java:7121)
09-22 07:16:41.848 +0000 17248 17248 E AndroidRuntime: at com.android.server.SystemServer.startBootstrapServices(SystemServer.java:1166)
09-22 07:16:41.848 +0000 17248 17248 E AndroidRuntime: at com.android.server.SystemServer.run(SystemServer.java:880)
09-22 07:16:41.848 +0000 17248 17248 E AndroidRuntime: at com.android.server.SystemServer.main(SystemServer.java:613)
09-22 07:16:41.848 +0000 17248 17248 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
09-22 07:16:41.848 +0000 17248 17248 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
09-22 07:16:41.848 +0000 17248 17248 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
09-22 07:16:41.850 +0000 17248 17248 E AndroidRuntime: Error reporting crash
09-22 07:16:41.850 +0000 17248 17248 E AndroidRuntime: java.lang.NullPointerException: Attempt to invoke interface method 'void android.app.IActivityManager.handleApplicationCrash(android.os.IBinder,android.app.ApplicationErrorReport$ParcelableCrashInfo)' on a null object reference
09-22 07:16:41.850 +0000 17248 17248 E AndroidRuntime: at com.android.internal.os.RuntimeInit$KillApplicationHandler.uncaughtException(RuntimeInit.java:156)
09-22 07:16:41.850 +0000 17248 17248 E AndroidRuntime: at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1073)
09-22 07:16:41.850 +0000 17248 17248 E AndroidRuntime: at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1068)
09-22 07:16:41.850 +0000 17248 17248 E AndroidRuntime: at java.lang.Thread.dispatchUncaughtException(Thread.java:2200)

分析過程:
(1) Settings$VersionInfo.fingerprint 為空,找到出現問題的代碼:
在這里插入圖片描述
(2)自己對源碼進行分析,發現一個方法,該方法能創建或者找到版本的信息,如果為空
則添加到集合中。而報錯的地方,是調用 getInternalVersion(),沒有做判空的處理。
在這里插入圖片描述
(3)繼續跟蹤代碼, mVersion 是一個集合,通過鍵值對來獲取那個值
在這里插入圖片描述
(4)UUID_PRIVATE_INTERNAL 是 null
在這里插入圖片描述
(5)猜想空指針異常可能是沒有調用 findOrCreateVersion(),沒有創建對應的值并且沒有
put 到集合中。并且打印了正常能開機的 mVersion 的大小,都是 2。
在這里插入圖片描述
修改方案如下:
在這里插入圖片描述


四、預防措施

為了減少應用程序崩潰的風險,可以采取以下預防措施:

  1. 良好的異常處理:在關鍵代碼塊中使用 try-catch 語句來捕獲和處理可能拋出的異常。這樣可以避免應用程序因為未處理的異常而崩潰,并提供更友好的用戶體驗。
  2. 合理地使用空值檢查:確保在訪問對象之前進行適當的空值檢查,以避免觸發空指針異常。
  3. 正確釋放資源:對于需要手動管理資源(如數據庫連接、文件流等),始終確保及時釋放這些資源,以避免資源泄漏和系統負載過高導致崩潰。
  4. 謹慎使用第三方庫:選擇可靠且經過廣泛測試的第三方庫,并仔細閱讀其文檔和源代碼。不推薦使用已知存在問題或長期無更新支持的庫。
  5. 定期進行性能優化和內存管理:通過減少內存占用、優化算法、限制并發線程數等方法,改善應用程序性能并減少崩潰風險。
  6. 多渠道測試與發布前驗證:在發布前進行全面測試,并覆蓋各種設備、操作系統版本和網絡條件下運行應用程序的場景。這有助于發現并修復潛在的崩潰問題。

五、參考鏈接

Android中Crash原理及監控處理
Android app 崩潰 & Crash 分析
Android Crash 問題分析以及解決


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/42061.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/42061.shtml
英文地址,請注明出處:http://en.pswp.cn/web/42061.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

p11函數和遞歸

遞歸與迭代 求n的階乘。&#xff08;不考慮溢出&#xff09; int Fac1(int n) {int i0;int ret1;for(i1;i<n;i){ret*i;}return ret; } int main(){//求n的階乘int n0;int ret0;scanf("%d",&n);retFac1(n);printf("%d\n",ret);return 0; } int Fac…

什么是激光導航和視覺導航技術

激光導航和視覺導航技術是現代導航系統中的兩種重要技術&#xff0c;它們在多個領域&#xff0c;如掃地機器人、無人機、機器人導航等中都有廣泛應用。以下是對這兩種技術的詳細介紹&#xff1a; 一、激光導航技術 1. 定義與原理 激光導航技術是一種利用激光束進行精確測量和…

ChatGPT:||是短路運算符,那么|、、是什么?

ChatGPT&#xff1a;||是短路運算符&#xff0c;那么|、&、&&是什么? 在Java中&#xff0c;邏輯運算符&&和||是短路邏輯運算符&#xff0c;而&和|是非短路邏輯運算符。 && 和 || 是短路邏輯運算符。當使用這些運算符時&#xff0c;如果第一個…

解決 Docker 容器鏡像拉取難題:全面指南

一、引言 在使用 Docker 容器的過程中&#xff0c;經常會遇到鏡像拉取慢甚至無法下載的問題&#xff0c;這給開發和部署工作帶來了不小的困擾。本文將深入探討這一問題的原因&#xff0c;并提供多種有效的解決方案。 二、問題原因分析 網絡限制 本地網絡帶寬不足或存在網絡擁…

unity知識點 專項四 一文徹底說清楚(錨點(anchor)、中心點(pivot)、位置(position)之間的關系)

一 概述 想要使UI控件在屏幕中達到正確的顯示效果&#xff0c;比如自適應屏幕尺寸、固定邊距等等&#xff0c;首先要理清楚幾個基本概念和設置&#xff1a;錨點(anchor)、中心點(pivot)、位置(position)、UI縮放模式、父物件的transform設置 二 Anchor、Pivot與Position 2…

網絡連接線相關問題

問題1&#xff1b; 直通線為什么兩頭都是T568B&#xff1f;是否可以兩臺T5568A&#xff1f;或者任意線序&#xff0c;只需兩頭一致&#xff1f; 不行&#xff0c;施工規范規定。&#xff08;原因&#xff1b;網線最長距離100m&#xff0c;實際用起來要把網線包管&#xff0c;走…

【分布式系統】Filebeat+Kafka+ELK 的服務部署

目錄 一.實驗準備 二.配置部署 Filebeat 三.配置Logstash 四.驗證 一.實驗準備 結合之前的博客中的實驗 主機名ip地址主要軟件es01192.168.80.101ElasticSearches02192.168.80.102ElasticSearches03192.168.80.103ElasticSearch、Kibananginx01192.168.80.104nginx、Logs…

iperf3: error - unable to connect to server: No route to host

1.確認iperf3版本是否統一。 2.確認防火墻是否關閉。 關閉防火墻 : systemctl stop firewalld 查看防火墻狀態: systemctl status firewalld 3.重新建起鏈接

Java進階----接口interface

接口 接口概述 接口是一種規范&#xff0c;使用接口就代表著要在程序中制定規范. 制定規范可以給不同類型的事物定義功能&#xff0c;例如&#xff1a; 利用接口&#xff0c;給飛機、小鳥制定飛行規范&#xff0c;讓其都具備飛行的功能&#xff1b;利用接口&#xff0c;給鼠…

SMU Summer 2024 Contest Round 1

A.Hcode OnlineJudge 給出一個N面骰子和整數K&#xff0c;擲出1-N之間的每個數的概率相同&#xff0c;每次擲出一次&#xff0c;記為成績&#xff0c;若成績小于K&#xff0c;則開始拋硬幣&#xff0c;硬幣朝上則數翻倍&#xff0c;反之則為0&#xff0c;概率都為0.5。當數大于…

自動駕駛算法———車道檢測(一)

“ 在本章中&#xff0c;我將指導您構建一個簡單但有效的車道檢測管道&#xff0c;并將其應用于Carla 模擬器中捕獲的圖像。管道將圖像作為輸入&#xff0c;并產生車道邊界的數學模型作為輸出。圖像由行車記錄儀&#xff08;固定在車輛擋風玻璃后面的攝像頭&#xff09;捕獲。…

【ZIP壓縮大揭秘】輕松掌握ZIP分卷壓縮包的高效解壓秘籍!

在這個信息爆炸的時代&#xff0c;文件大小常常成為我們分享與存儲的絆腳石。幸運的是&#xff0c;ZIP分卷壓縮技術如同一把鑰匙&#xff0c;巧妙地將龐然大物分解成小巧易管理的部分。但面對這一串分卷壓縮包&#xff0c;你是否也曾迷茫于如何高效解壓&#xff0c;恢復文件的完…

解碼Python字符串:‘r‘、‘b‘、‘u‘和‘f‘前綴的全面指南

&#x1f4d6; 正文 1 字符串前加’r’ 表示原始字符串&#xff0c;消除轉義 print(abc\nde) # abc # deprint(rabc\nde) # abc\nde在下面這個列子中&#xff0c;如果不在路徑字符串前面加r那么&#xff0c;路徑中的空格就會出現問題 print(rD:\01 programming\09python\py…

全志A527 T527 cat /proc/cupinfo沒有Serial問題

1.前言 我們有些客戶是使用cpuinfo節點去獲取系統的cpuid的,如下: cat /proc/cupinfo processor : 0 BogoMIPS : 48.00 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp CPU impleme…

系統吃swap問題排查

目錄 背景 問題 分析并解決 1.控制線程數 2.更換IO組件 3.Linux進程信息文件分析 總結加餐 參考文檔 背景 隔壁業務組系統是簡單的主從結構&#xff0c;寫索引的服務(主)叫primary&#xff0c; 讀索引并提供搜索功能的服務(從)叫replica。業務線同步數據并不是平滑的&…

離散化及其在 Pandas 中的實現方法

目錄 1.什么是離散化&#xff1f; 2.離散化類型 3.示例代碼 3.1連續變量離散化 3.2定性變量離散化 4.運行結果 4.1連續變量離散化 4.2定性變量離散化 1.什么是離散化&#xff1f; 離散化是將連續數據或分類數據轉換為離散類別的過程&#xff0c;方便后續的數據分析和機…

static的理論學習

在說到static之前&#xff0c;需要先明確變量類型&#xff1a; 而在聊到變量類型之前我們可以將變量的兩個屬性好好學一學 變量的兩個屬性 作用域&#xff08;scope&#xff09;&#xff1a; 從內存的角度來看&#xff0c;就是變量存放在棧&#xff08;stack&#xff09;中&…

在 JavaScript 中,??(雙問號運算符)和 ?.(可選鏈運算符)區別

在 JavaScript 中&#xff0c;??&#xff08;雙問號運算符&#xff09;和 ?.&#xff08;可選鏈運算符&#xff09;是兩種不同的運算符&#xff0c;用于處理不同的情況&#xff1a; 雙問號運算符 (??): ?? 運算符是空值合并運算符&#xff08;Nullish Coalescing Oper…

Android C++系列:Linux進程(一)

1. 進程概念 我們知道,每個進程在內核中都有一個進程控制塊(PCB)來維護進程相關的信 息,Linux內核的進程控制塊是task_struct結構體。現在我們全面了解一下其中都有哪 些信息。 進程id。系統中每個進程有唯一的id,在C語言中用pid_t類型表示,其實就是一個非 負整數。進程的…

TypeError: Cannot read properties of null (reading ‘nextSibling‘)

做項目用的Vue3Vite, 在畫靜態頁面時&#xff0c;點擊菜單跳轉之后總是出現如下報錯&#xff0c;百思不得其解。看了網上很多回答&#xff0c;也沒有解決問題&#xff0c;然后試了很多方法&#xff0c;最后竟然發現是template里邊沒有結構的原因。。。 原來我的index.vue是這樣…