前言
Android系統(tǒng)在應(yīng)用發(fā)生Crash/ANR的時(shí)候,總會(huì)彈出一個(gè)提示對(duì)話框送膳,但是現(xiàn)在部分客戶不想要這樣的對(duì)話框员魏,要求移除
一、Application Crash
表現(xiàn): 程序崩潰或閃退叠聋,界面上通常會(huì)出現(xiàn)“應(yīng)用已停止運(yùn)行”的提示撕阎。
常見原因(Java異常):
錯(cuò)誤類型 | 詳細(xì)描述 |
---|---|
NullPointerException | 嘗試在需要對(duì)象的地方使用了null。 |
SQLException | 數(shù)據(jù)庫(kù)操作錯(cuò)誤碌补,如SQL語(yǔ)句錯(cuò)誤虏束、數(shù)據(jù)庫(kù)連接問題等。 |
ClassCastException | 嘗試將對(duì)象強(qiáng)制轉(zhuǎn)換為不是其實(shí)例的子類厦章。 |
NumberFormatException | 將字符串轉(zhuǎn)換為數(shù)字時(shí)格式不正確镇匀。 |
ClassNotFoundException | 嘗試加載的類在類路徑中找不到。 |
ArithmeticException | 數(shù)學(xué)運(yùn)算錯(cuò)誤袜啃,如除以零汗侵。 |
ArrayIndexOutOfBoundsException | 數(shù)組索引越界。 |
IllegalArgumentException | 向方法傳遞了非法或不適當(dāng)?shù)膮?shù)囊骤。 |
IllegalAccessException | 嘗試訪問或修改類的字段晃择,但當(dāng)前方法沒有足夠的訪問權(quán)限。 |
ArrayStoreException | 試圖將錯(cuò)誤類型的對(duì)象存儲(chǔ)到數(shù)組中也物。 |
Native Crash(C++層):
Native Crash發(fā)生在C++代碼層宫屠,Java層難以直接捕獲錯(cuò)誤信息,通常表現(xiàn)為應(yīng)用閃退滑蚯±缩澹可通過Monkey測(cè)試等自動(dòng)化測(cè)試工具進(jìn)行監(jiān)控抵栈。
具體原因:
- 設(shè)備碎片化:不同設(shè)備間的兼容性問題。
- 網(wǎng)絡(luò)問題:帶寬不足坤次、網(wǎng)絡(luò)切換等古劲。
- 內(nèi)存管理:內(nèi)存泄漏、非授權(quán)內(nèi)存訪問等缰猴。
- 用戶負(fù)載:高并發(fā)用戶導(dǎo)致的資源競(jìng)爭(zhēng)产艾。
- 代碼錯(cuò)誤:空指針訪問、非法指令執(zhí)行等滑绒。
- 第三方服務(wù):如廣告插件或第三方庫(kù)的不穩(wěn)定闷堡。
測(cè)試中如何關(guān)注:
- 界面操作驗(yàn)證:確保所有按鈕、控件操作有效疑故,響應(yīng)正確杠览。
- 負(fù)載測(cè)試:通過自動(dòng)化工具進(jìn)行長(zhǎng)時(shí)間或高負(fù)載測(cè)試,暴露潛在問題纵势。
- 重復(fù)操作測(cè)試:多次重復(fù)相同操作踱阿,檢查是否出現(xiàn)崩潰。
- 異常輸入測(cè)試:對(duì)輸入框進(jìn)行非標(biāo)準(zhǔn)輸入钦铁,檢查應(yīng)用的容錯(cuò)能力软舌。
解決方法:
- 查看日志文件中的am_crash相關(guān)條目,定位崩潰點(diǎn)牛曹。
- 根據(jù)日志中的堆棧跟蹤葫隙,分析并修復(fù)代碼問題。
二躏仇、ANR(Application Not Responding)
表現(xiàn): 應(yīng)用無響應(yīng),用戶界面卡住腺办,系統(tǒng)彈出等待或強(qiáng)制關(guān)閉的對(duì)話框焰手。
對(duì)應(yīng)用的影響:
- 用戶體驗(yàn)差,可能導(dǎo)致用戶流失怀喉。
- 操作中斷书妻,可能造成數(shù)據(jù)丟失。
產(chǎn)生原因:
- 主線程阻塞:UI線程在5秒內(nèi)未響應(yīng)輸入事件躬拢。
- BroadcastReceiver超時(shí):未在10秒內(nèi)完成處理并返回躲履。
根本原因:
- 主線程執(zhí)行了耗時(shí)的IO操作(如數(shù)據(jù)庫(kù)讀寫、網(wǎng)絡(luò)請(qǐng)求)聊闯。
- CPU資源被其他應(yīng)用或線程占用工猜,導(dǎo)致主線程得不到足夠的時(shí)間片。
測(cè)試中如何關(guān)注:
- 耗時(shí)操作監(jiān)控:關(guān)注上傳大文件菱蔬、保存復(fù)雜數(shù)據(jù)等操作的響應(yīng)時(shí)間篷帅。
- 網(wǎng)絡(luò)壓力測(cè)試:在網(wǎng)絡(luò)狀況不佳或變化時(shí)測(cè)試應(yīng)用穩(wěn)定性史侣。
- Monkey測(cè)試:通過隨機(jī)事件生成器模擬用戶操作,檢測(cè)ANR問題魏身。
- 內(nèi)存和CPU監(jiān)控:在多任務(wù)惊橱、多線程場(chǎng)景下監(jiān)測(cè)資源使用情況。
解決方法:
- 在log文件夾中搜索am_anr或activitymanager: ANR箭昵,查找ANR日志税朴。
- 分析data_app_anr@xxx.txt文件中的異常堆棧,特別是主線程(main prio=5 tid=1)的阻塞情況家制。
- 根據(jù)日志信息正林,優(yōu)化代碼,避免在主線程中執(zhí)行耗時(shí)操作慰丛,或使用異步編程模型處理耗時(shí)任務(wù)卓囚。
代碼示例
在常規(guī)開發(fā)中付魔,經(jīng)常遇到手機(jī)性能較低坡脐,以上優(yōu)化方法提升不大的情況下,建議直接屏蔽彈窗
diff --git a/frameworks/base/services/core/java/com/android/server/am/ErrorDialogController.java b/frameworks/base/services/core/java/com/android/server/am/ErrorDialogController.java
old mode 100644
new mode 100755
index 82f35adbb13..a0942face68
--- a/frameworks/base/services/core/java/com/android/server/am/ErrorDialogController.java
+++ b/frameworks/base/services/core/java/com/android/server/am/ErrorDialogController.java
@@ -35,6 +35,9 @@ final class ErrorDialogController {
private final ActivityManagerService mService;
private final ActivityManagerGlobalLock mProcLock;
+ // Create by yeruilai 2024-8-29 15:57:56 Block ANR and Crash error dialogs
+ private static final boolean mShowDialog = !Build.IS_USER;
+
/**
* Dialogs being displayed due to crash.
*/
@@ -179,7 +182,13 @@ final class ErrorDialogController {
dialogs = mCrashDialogs;
}
if (dialogs != null) {
- forAllDialogs(dialogs, Dialog::show);
+ // Create by yeruilai 2024-9-2 10:24:07 Block ANR and Crash error dialogs
+ // forAllDialogs(dialogs, Dialog::show);
+ if(mShowDialog) {
+ forAllDialogs(dialogs, Dialog::show);
+ } else {
+ forAllDialogs(dialogs, Dialog::dismiss);
+ }
}
});
}
@@ -193,7 +202,13 @@ final class ErrorDialogController {
final Context c = contexts.get(i);
mAnrDialogs.add(new AppNotRespondingDialog(mService, c, data));
}
- scheduleForAllDialogs(mAnrDialogs, Dialog::show);
+ // Create by yeruilai 2024-9-2 10:24:07 Block ANR and Crash error dialogs
+ // scheduleForAllDialogs(mAnrDialogs, Dialog::show);
+ if(mShowDialog) {
+ scheduleForAllDialogs(mAnrDialogs, Dialog::show);
+ } else {
+ scheduleForAllDialogs(mAnrDialogs, Dialog::dismiss);
+ }
}
@GuardedBy("mProcLock")