1. ANRの定義
Android アプリケーションのメイン スレッドが長時間ブロックされているため、「アプリケーションが応答していません」(Anr) エラーが発生します。アプリケーションがフォアグラウンドにある場合は、ポップアップ ウィンドウが表示されます。
2. ANR の理由
1. メインスレッドの時間のかかる操作
2. メインスレッドが子スレッドによって同期的にロックされている
3. メインスレッドがバインダーピアによってブロックされている
4. バインダースレッドがいっぱいである
5. システムリソースを取得できない
3. いくつかの種類の ANR
1. Service TimeOut タイムアウト
タイムアウト理由:
サービス ライフサイクル メソッド実行時のタイムアウト: oncreate、onstart onbind タイムアウト
時間: フォアグラウンド サービスの場合は 20 秒、バックグラウンド サービスの場合は 200 秒
2.BroadCast TimeOut ブロードキャスト タイムアウトのタイムアウト
理由:
指定された時刻に、onReceive メソッドが実行されますタイムアウト
タイムアウト時間: フォアグラウンドで 10 秒、バックグラウンドで 60 秒
3. InputDispatching タイムアウト
クリックなどの入力イベントのタイムアウト、タッチ イベントへの応答なし
タイムアウト時間: 5 秒
ServiceTimeout トリガー メカニズム
BumpServiceExecutingLocked(); 爆弾を埋め込み、対応するライフサイクルが対応する時間内に実行されなかった場合はエラーとなり、処理された場合はremovemsgを送信し
ます
void scheduleServiceTimeoutLocked(ProcessRecord proc) {
if (proc.executingServices.size() == 0 || proc.thread == null) {
return;
}
Message msg = mAm.mHandler.obtainMessage(
ActivityManagerService.SERVICE_TIMEOUT_MSG);
msg.obj = proc;
mAm.mHandler.sendMessageDelayed(msg,
proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
}
SERVICE_TIMEOUT_MSG メッセージを処理する
com.android.server.am.ActivityManagerService#SERVICE_TIMEOUT_MSG
case SERVICE_TIMEOUT_MSG: {
mServices.serviceTimeout((ProcessRecord)msg.obj);
} break;
//日志里的第一现场:Timeout executing service
Slog.w(TAG, "Timeout executing service: " + timeout);
StringWriter sw = new StringWriter();
PrintWriter pw = new FastPrintWriter(sw, false, 1024);
pw.println(timeout);
timeout.dump(pw, " ");
pw.close();
mLastAnrDump = sw.toString();
mAm.mHandler.removeCallbacks(mLastAnrDumpClearer);
mAm.mHandler.postDelayed(mLastAnrDumpClearer, LAST_ANR_LIFETIME_DURATION_MSECS);
anrMessage = "executing service " + timeout.shortInstanceName;
ブロードキャスト タイムアウト トリガー メカニズム:
ブロードキャストは次の 2 つに分類されます。タイムアウトを引き起こすシリアル ブロードキャスト、パラレルブロードキャストはシリアルブロードキャストです。
動的登録を伴う規則的なブロードキャスト
静的登録ブロードキャスト
2. ANR測位プロセス
1. logcat を通じて ANR を表示して、CPU 情報とシステム負荷ステータス、
APK パッケージ名、プロセス番号、ANR をトリガーした理由、ANR が発生した期間中のシステム内の各アプリケーションの CPU 使用率 (入力タイムアウトなど) を表示します
。 、ANR はタイムアウト時間に基づいています。5 秒間押し続け、アプリケーションがフィルターに応答していないことを使用し、モンキー ログをフィルターします。
2. anr のログを検索し、メイン スレッド main のトレース ログ情報
/data/anrを確認します
。 3. ANR が発生した特定の期間を特定します
。 4. ANR が発生した期間中のシステムの状態を確認します。
3. ANR を回避する方法: メインスレッドの時間のかかる操作を削減します。
1.ServiceTimeout は
、時間のかかるアプリケーションの作成を回避
し、時間のかかるサービス ライフ サイクルを回避します
。IntentService を使用できます
。2.BroadCastTimeout
は、IntentService を使用できます
。3.InputDispatching Timeout は
、時間のかかるメイン スレッドを回避します。
4. 合理的なパフォーマンスの最適化により、次のような問題も回避できます。
1. while または ondraw での新しいオブジェクトを避ける
2. オブジェクト プール Android.util.Pools を使用する
3. 冗長な背景画像、特に親レイアウトの背景画像をチェックする
4. レイアウト レベルを下げる: constrainlayout、merge
5. レイアウト ビュータブの読み込みを遅延する
4. ANR検出ツール
blockcanary
strictmode
leadcanary