ANR (Application Not Responding) - Kesalahan yang terjadi ketika aplikasi tidak merespons. Akibatnya, kotak dialog terbuka yang meminta pengguna untuk menunggu atau menutup aplikasi.

Kondisi PPA
- Acara masukan (tombol dan acara sentuh) tidak diproses selama 5 detik;
- BroadcastReceiver (onRecieve ()) tidak diproses dalam waktu yang ditentukan (foreground - 10 s, background - 60 s);
- ContentProvider tidak selesai dalam 10 detik.
Biasanya utas utama diblokir.
Jika Anda membaca artikel saya, Anda mungkin sudah terbiasa dengan fakta bahwa kami merangkak ke dalam kode sumber. Jadi mari kita lihat seperti apa
PPA di bawah tenda .
Kelas
AppErrors menangani tidak hanya ANR, tetapi juga kesalahan lain yang mungkin terjadi dalam aplikasi, termasuk crash. Metode handleShowAnrUi () baru saja membuka jendela menakutkan ini bagi banyak pengembang dan pengguna yang menampilkan ANR.
class AppErrors { ... void handleShowAnrUi(Message msg) { Dialog dialogToShow = null; synchronized (mService) { AppNotRespondingDialog.Data data = (AppNotRespondingDialog.Data) msg.obj; final ProcessRecord proc = data.proc; if (proc == null) { Slog.e(TAG, "handleShowAnrUi: proc is null"); return; } if (proc.anrDialog != null) { Slog.e(TAG, "App already has anr dialog: " + proc); MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR, AppNotRespondingDialog.ALREADY_SHOWING); return; } Intent intent = new Intent("android.intent.action.ANR"); if (!mService.mProcessesReady) { intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND); } mService.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID, 0 ); boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; if (mService.canShowErrorDialogs() || showBackground) { dialogToShow = new AppNotRespondingDialog(mService, mContext, data); proc.anrDialog = dialogToShow; } else { MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR, AppNotRespondingDialog.CANT_SHOW);
Namun, PPA tidak dimulai di sini. Seperti yang saya katakan di atas, salah satu penyebab pertama kesalahan ini adalah keterlambatan acara input, yaitu 5 detik. Dengan pencarian singkat, kita dapat menemukan di mana nilai ini ditetapkan.
namespace android {
Sekarang kita dapat melihat kode tempat bagian asli dipanggil. Ini terjadi di kelas
InputManagerService .
Dan di sini adalah mWindowManagerCallbacks di
InputMonitor :
if (appWindowToken != null && appWindowToken.appToken != null) {
Mari kita lihat lebih dekat inputDispatchingTimedOut (). Di sini kami hanya menampilkan pesan melalui ActivityManager tentang berakhirnya batas waktu dan membiarkan pengguna memutuskan apakah akan membatalkan tindakan atau terus menunggu. Dan di
ActivityManagerService , AppErrors disebut dalam kasus crash atau ANR.
private boolean makeAppCrashingLocked(ProcessRecord app, String shortMsg, String longMsg, String stackTrace) { app.crashing = true; app.crashingReport = generateProcessError(app, ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); startAppProblemLocked(app); app.stopFreezingAllLocked(); return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); } private void makeAppNotRespondingLocked(ProcessRecord app, String activity, String shortMsg, String longMsg) { app.notResponding = true; app.notRespondingReport = generateProcessError(app, ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, activity, shortMsg, longMsg, null); startAppProblemLocked(app); app.stopFreezingAllLocked(); }
Penyebab utama PPA
- Kunci input / output
- Kemacetan jaringan
- Pemblokiran utas
- Loop tanpa ujung
- Logika bisnis terlalu lama
Menghindari ANR
- Utas antarmuka pengguna utama menjalankan logika yang hanya terkait dengan antarmuka pengguna;
- Perhitungan kompleks (misalnya, operasi basis data, operasi input-output, operasi jaringan, dll.) Dilakukan dalam aliran terpisah;
- Gunakan Handler untuk berinteraksi antara utas antarmuka pengguna dan alur kerja;
- Gunakan RxJava dll. untuk menangani operasi asinkron.
Cara menangkap PPA
PS Saya menerbitkan semua pilihan di saluran telegram
@paradisecurity .