ANR'leri teşhis etme ve düzeltme

Bir Android uygulamasının kullanıcı arayüzü iş parçacığı çok uzun süre engellendiğinde sistem "Uygulama Yanıt Vermiyor" (ANR) hatası gönderir. Bu sayfada farklı ANR türleri, bunların nasıl teşhis edileceği ve çözüm önerileri açıklanmaktadır. Listelenen tüm varsayılan zaman aşımı zaman aralıkları AOSP ve Pixel cihazlar içindir. Bu süreler OEM'ye göre değişebilir.

ANR'lerin nedenini belirlerken sistem ve uygulama sorunlarını ayırt etmenin faydalı olduğunu unutmayın.

Sistem kötü bir durumda olduğunda aşağıdaki sorunlar ANR'lere neden olabilir:

  • Sistem sunucusundaki geçici sorunlar genellikle hızlı bağlayıcı çağrılarının yavaş olmasına neden olur.
  • Sistem sunucusu ve yüksek cihaz yüküyle ilgili sorunlar, uygulama ileti dizilerinin planlanmamasına neden olur.

Kullanabiliyorsanız sistem ve uygulama sorunlarını ayırt etmenin iyi bir yolu Perfetto izlerini kullanmaktır:

  • Çalışan veya çalıştırılabilir olup olmadığını görmek için Perfetto'daki iş parçacığı durumu takibine bakarak uygulamanın ana iş parçacığının planlanıp programlanmadığını görebilirsiniz.
  • Kilit anlaşmazlığı gibi sorunlar için system_server ileti dizilerine bakın.
  • Bağlayıcı çağrıları yavaş için neden yavaş olduğunu görmek için varsa yanıt ileti dizisine bakın.

Giriş gönderme zaman aşımı

Giriş dağıtımı ANR'leri, uygulamanın ana iş parçacığı kaydırma veya tuşa basma gibi bir giriş etkinliğine zamanında yanıt vermediğinde meydana gelir. Giriş dağıtımı zaman aşımları meydana geldiğinde uygulama ön planda bulunduğundan, bunlar kullanıcılar tarafından hemen hemen her zaman görülebilir ve azaltılması çok önemlidir.

Varsayılan zaman aşımı süresi: 5 saniye.

Giriş dağıtımı ANR'leri genellikle ana iş parçacığındaki sorunlardan kaynaklanır. Ana iş parçacığı kilit almayı beklerken engellenmişse muhafaza iş parçacığı da dahil olabilir.

Giriş gönderme ANR'lerini önlemek için aşağıdaki en iyi uygulamaları izleyin:

  • Ana iş parçacığında engelleme veya uzun süreli işlemler gerçekleştirmeyin. Ana iş parçacığındaki yanlışlıkla yapılan etkinlikleri yakalamak için StrictMode kullanmayı düşünün.
  • Ana iş parçacığı ile diğer ileti dizileri arasındaki kilit anlaşmazlığını en aza indirin.
  • Yayınların işlenmesi veya hizmetleri çalıştırma gibi işlemlerde ana iş parçacığında kullanıcı arayüzü olmayan işleri en aza indirin.

Yaygın nedenler

Giriş gönderme ANR'leriyle ilgili bazı yaygın nedenler ve önerilen düzeltmeleri burada bulabilirsiniz.

Neden Ne olur? Önerilen düzeltmeler
Bağlayıcı çağrısı yavaş Ana iş parçacığı uzun bir eşzamanlı bağlayıcı çağrısı yapar. Çağrıyı ana iş parçacığının dışına taşıyın veya API'nin sahibiyseniz çağrıyı optimize etmeye çalışın.
Çok sayıda art arda bağlayıcı çağrısı Ana iş parçacığı art arda birçok eşzamanlı bağlayıcı çağrısı yapar. Bağlayıcı çağrılarını dar bir döngü içinde gerçekleştirmeyin.
Engelleme G/Ç Ana iş parçacığı, veritabanı veya ağ erişimi gibi engelleme G/Ç çağrısı yapar. Tüm engelleme KS'lerini ana iş parçacığının dışına taşıyın.
Kilit anlaşmazlığı Ana iş parçacığı kilit almayı beklerken engellendi. Ana ileti dizisi ile diğer ileti dizisi arasındaki kilit anlaşmazlığını azaltın. Diğer iş parçacığındaki yavaş kodu optimize edin.
Pahalı çerçeve Tek bir karede çok fazla oluşturma işlemi yapıldığında ciddi olumsuzluklar ortaya çıkıyor. Çerçeveyi oluşturmak için daha az işlem yapın. n2 algoritmalarını kullanmayın. Kaydırma veya sayfalama gibi işlemler için etkili bileşenler (ör. Jetpack çağrı kitaplığı) kullanın.
Diğer bileşen tarafından engellendi Yayın alıcısı gibi farklı bir bileşen çalışıyor ve ana iş parçacığını engelliyor. Kullanıcı arayüzü olmayan işleri ana iş parçacığından mümkün olduğunca uzaklaştırın. Yayın alıcılarını farklı bir iş parçacığında çalıştırın.
GPU'da takılma GPU'nun takılması, oluşturma işleminin engellenmesine ve dolayısıyla da giriş dağıtımı ANR'sine neden olan bir sistem veya donanım sorunudur. Maalesef genellikle uygulama tarafında herhangi bir düzeltme yapılmaz. Mümkünse sorunları gidermek için donanım ekibiyle iletişime geçin.

Hata ayıklama

Google Play Console veya Firebase Crashlytics'teki ANR kümesi imzasına bakarak hata ayıklamaya başlayın. Küme genellikle ANR'ye neden olduğundan şüphelenilen üst çerçeveleri içerir.

Aşağıdaki akış grafiğinde, giriş zaman aşımı gönderim ANR'sinin nedeninin nasıl belirleneceği gösterilmektedir.

Şekil 1. Giriş gönderme ANR'sinde hata ayıklama.

Play vitals, bu yaygın ANR nedenlerinden bazılarını algılayıp hata ayıklamaya yardımcı olabilir. Örneğin, vitals, kilit anlaşmazlığı nedeniyle bir ANR'nin meydana geldiğini tespit ederse ANR Analizleri bölümünde sorunu özetleyebilir ve önerilen düzeltmeyi yapabilir.

Şekil 2. Play vitals ANR algılama.

Odaklanılan pencere yok

Dokunma gibi etkinlikler, isabet testine göre doğrudan ilgili pencereye gönderilirken, anahtarlar gibi etkinliklerin bir hedefi olması gerekir. Bu hedefe odaklanan pencere adı verilir. Ekran başına yalnızca bir tane odaklanmış pencere vardır ve bu, genellikle kullanıcının etkileşimde bulunduğu penceredir. Odaklanılan pencere bulunamazsa giriş, odaksız pencere ANR'sini tetikler. Odaklanmamış pencere ANR'si, bir tür giriş dağıtımı ANR'sidir.

Varsayılan zaman aşımı süresi: 5 saniye.

Yaygın nedenler

Odaklanmamış pencere ANR'leri genellikle aşağıdaki sorunlardan birinden kaynaklanır:

  • Uygulama çok fazla iş yapıyor ve ilk kareyi çizemeyecek kadar yavaş.
  • Ana pencereye odaklanılamıyor. Bir pencere FLAG_NOT_FOCUSABLE ile işaretlenmişse kullanıcı bu pencereye anahtar veya düğme etkinliği gönderemez.

Kotlin

override fun onCreate(savedInstanceState: Bundle) {
  super.onCreate(savedInstanceState)
  setContentView(R.layout.activity_main)
  window.addFlags(WindowManager.LayoutParams.FLAG_FLAG_NOT_FOCUSABLE)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
}

Yayın alıcısı zaman aşımı

Yayın alıcısı ANR'si, yayın alıcısı yayını zamanında işlemediğinde ortaya çıkar. Eşzamanlı alıcılar veya goAync() numaralı telefonu aramayan alıcılar için zaman aşımı, onReceive() aracının zamanında tamamlanmadığı anlamına gelir. Eş zamansız alıcılar veya goAsync() çağrısı yapan alıcılar için zaman aşımı, PendingResult.finish() hizmetinin zamanında çağrılmadığı anlamına gelir.

Yayın alıcı ANR'leri genellikle şu ileti dizilerinde meydana gelir:

  • Sorun, uygulamanın yavaş başlaması ise ana iş parçacığı.
  • Sorun, onReceive() kodu yavaşsa yayın alıcısını çalıştıran iş parçacığı.
  • Sorun yavaşsa goAsync() yayın kodu çalışan ileti dizilerini yayınlayın.

Yayın alıcısı ANR'lerini önlemek için aşağıdaki en iyi uygulamaları izleyin:

  • Uygulama, yayını işlemeye başlarsa ANR zaman aşımında sayılacağından uygulama başlatmanın hızlı olduğundan emin olun.
  • goAsync() kullanılıyorsa PendingResult.finish() ürününün hızlı bir şekilde çağrıldığından emin olun. Bu durum, eşzamanlı yayın alıcılarıyla aynı ANR zaman aşımı durumuna tabidir.
  • goAsync() kullanılıyorsa çalışan iş parçacıklarının başka uzun süreli veya engelleyen işlemlerle paylaşılmadığından emin olun.
  • Ana iş parçacığında çalışan kullanıcı arayüzü kodunun engellenmesini önlemek için registerReceiver() kullanarak yayın alıcılarını ana olmayan bir iş parçacığında çalıştırabilirsiniz.

Zaman aşımı süreleri

Yayın alma zaman aşımı süreleri, ön plan intent işaretinin ayarlanıp ayarlanmadığına ve platform sürümüne bağlıdır.

Amaç türü Android 13 ve önceki sürümler Android 14 ve sonraki sürümler

Ön plan öncelikli amacı

(FLAG_RECEIVER_FOREGROUND ayarlandı)

10 saniye

İşlemin CPU açısından yeterli olup olmadığına bağlı olarak 10-20 saniye

Arka plan önceliği amacı

(FLAG_RECEIVER_FOREGROUND ayarlanmadı)

60 saniye

İşlemin CPU açısından yeterli olup olmadığına bağlı olarak 60-120 saniye

FLAG_RECEIVER_FOREGROUND işaretinin ayarlanıp ayarlanmadığını anlamak için ANR konusunda "flg=" ifadesini arayın ve 0x10000000 olup olmadığını kontrol edin. Bu bit ayarlanırsa amacın FLAG_RECEIVER_FOREGROUND ayarı vardır ve dolayısıyla zaman aşımı daha kısa olur.

Kısa yayın zaman aşımına (10-20 saniye) sahip ANR konusu örneği:

Broadcast of Intent { act=android.inent.action.SCREEN_ON flg=0x50200010 }

Uzun yayın zaman aşımına (60-120 saniye) sahip ANR konusu örneği:

Broadcast of Intent { act=android.intent.action.TIME_SET flg=0x25200010 }

Yayın süreleri nasıl ölçülür?

Yayın süresi ölçümü, yayın system_server uygulamasından uygulamaya gönderildiğinde başlar ve uygulama yayını işlemeyi bitirdiğinde sona erer. Uygulama işlemi daha önce çalışmıyorsa ANR zaman aşımı süresi içinde bir baştan başlatma işlemi de yapmalıdır. Bu nedenle, uygulamanın yavaş başlatılması yayın alıcısı ANR'lerine yol açabilir.

Aşağıdaki şekilde, yayın alıcısı ANR zaman çizelgesinin belirli uygulama süreçleriyle uyumlu olduğu gösterilmektedir.

Şekil 3. Yayın alıcısı ANR zaman çizelgesi.

ANR zaman aşımı ölçümü, alıcı yayını işlemeyi bitirdiğinde sona erer. Bu işlemin tam olarak ne zaman gerçekleştiği, eşzamansız veya eşzamansız alıcı olmasına bağlıdır.

  • Eşzamanlı alıcılar için onReceive() döndürüldüğünde ölçüm durur.
  • Eşzamansız alıcılar için ölçüm, PendingResult.finish() çağrıldığında durur.
Şekil 4. Eşzamanlı ve eşzamansız alıcılar için ANR zaman aşımı ölçümü uç noktaları.

Yaygın nedenler

Yayın alıcı ANR'leriyle ilgili bazı yaygın nedenler ve önerilen düzeltmeleri burada bulabilirsiniz.

Neden Geçerlilik kapsamı: Ne oldu? Önerilen düzeltme
Yavaş uygulama başlatma Tüm alıcılar Uygulamanın baştan başlatma işlemi çok uzun sürdü. Yavaş uygulama başlatmayı optimize edin.
onReceive() planlanmadı Tüm alıcılar Yayın alıcısı iş parçacığı başka bir iş yapmakla meşgul olduğundan onReceive() yöntemini başlatamadı. Alıcı iş parçacığında uzun süreli görevler gerçekleştirmeyin (veya alıcıyı özel iş parçacığına taşımayın).
onReceive() yavaş Tüm alıcılar, ancak çoğunlukla eşzamanlı olanlar onReceive() yöntemi başladı ancak engellenmiş veya yavaş olduğundan zamanında tamamlanamadı. Yavaş alıcı kodunu optimize edin.
Eş zamansız alıcı görevleri planlanmadı goAsync() alıcılar onReceive() yöntemi, engellenen bir çalışan iş parçacığı havuzunda iş yürütmeye çalıştığından çalışma başlamadı. Yavaş veya engelleme çağrılarını optimize edin ya da yayın çalışanları için farklı uzun süreli görevlere kıyasla farklı iş parçacıkları kullanın.
Yavaş veya engellenmiş çalışanlar goAsync() alıcı Yayın işlenirken çalışan iş parçacığı havuzunun bir yerinde engelleme veya yavaş bir işlem oluştu. Bu nedenle, PendingResult.finish zamanında çağrılmadı. Yavaş async alıcı kodunu optimize edin.
PendingResult.finish numaralı telefonu aramayı unuttum goAsync() alıcı Kod yolunda finish() çağrısı eksik. finish() uygulamasının her zaman çağrıldığından emin olun.

Hata ayıklama

Küme imzasına ve ANR raporuna göre alıcının üzerinde çalıştığı iş parçacığını ve ardından eksik veya yavaş çalışan belirli kodu bulabilirsiniz.

Aşağıdaki akış grafiğinde, yayın alıcısı ANR'sinin nedeninin nasıl belirleneceği gösterilmektedir.

Şekil 5. Yayın alıcısı ANR'sinde hata ayıklama.

Alıcı kodunu bulun

Google Play Console, ANR imzasında alıcı sınıfı ve yayın amacını gösterir. Aşağıdakileri arayın:

  • cmp=<receiver class>
  • act=<broadcast_intent>

Yayın alıcısı ANR imzası örneği aşağıda verilmiştir:

com.example.app.MyClass.myMethod
Broadcast of Intent { act=android.accounts.LOGIN_ACCOUNTS_CHANGED
cmp=com.example.app/com.example.app.MyAccountReceiver }

onReceive() yöntemini çalıştıran iş parçacığını bulun

Özel işleyici belirtmek için Context.registerReceiver kullanıyorsanız bu işleyiciyi çalıştıran iş parçacığıdır. Aksi takdirde bu, ana iş parçacığıdır.

Örnek: planlanmamış eş zamansız alıcı görevleri

Bu bölümde, yayın alıcısı ANR'sinde hata ayıklamayla ilgili bir örnek gösterilmektedir.

ANR imzasının aşağıdaki gibi göründüğünü varsayalım:

com.example.app.MyClass.myMethod
Broadcast of Intent {
act=android.accounts.LOG_ACCOUNTS_CHANGED cmp=com.example.app/com.example.app.MyReceiver }

İmzaya göre yayın amacının android.accounts.LOG_ACCOUNTS_CHANGED ve alıcı sınıfının com.example.app.MyReceiver olduğu anlaşılıyor.

Alıcı kodundan, "BG Thread [0,1,2,3]" iş parçacığı havuzunun bu yayını işlemek için asıl işi yaptığını belirleyebilirsiniz. Yığın dökümlerine baktığınızda, dört arka plan (BG) iş parçacığının aynı kalıba sahip olduğunu görebilirsiniz: getDataSync engelleme çağrısı yürütüyorlar. Tüm BG ileti dizileri meşgul olduğundan yayın zamanında işlenemedi ve bu nedenle ANR'ye yol açıyordu.

BG Thread #0 (tid=26) Waiting

at jdk.internal.misc.Unsafe.park(Native method:0)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture:563)
at com.google.common.util.concurrent.ForwardingFuture.get(ForwardingFuture:68)
at com.example.app.getDataSync(<MyClass>:152)

...

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
at com.google.android.libraries.concurrent.AndroidExecutorsModule.lambda$withStrictMode$5(AndroidExecutorsModule:451)
at com.google.android.libraries.concurrent.AndroidExecutorsModule$$ExternalSyntheticLambda8.run(AndroidExecutorsModule:1)
at java.lang.Thread.run(Thread.java:1012)
at com.google.android.libraries.concurrent.ManagedPriorityThread.run(ManagedPriorityThread:34)

There are several approaches to fix the issue:

  • Find out why getDataSync is slow and optimize.
  • Don't run getDataSync on all four BG threads.
  • More generally, ensure that the BG thread pool isn't saturated with long-running operations.
  • Use a dedicated thread pool for goAsync worker tasks.
  • Use an unbounded thread pool instead of the bounded BG thread pool

Example: slow app startup

A slow app startup can cause several types of ANRs, especially broadcast receiver and execute service ANRs. The cause of an ANR is likely slow app startup if you see ActivityThread.handleBindApplication in the main thread stacks.

Execute service timeout

An execute service ANR happens when the app's main thread doesn't start a service in time. Specifically, a service doesn't finish executing onCreate() and onStartCommand() or onBind() within the timeout period.

Default timeout period: 20 seconds for foreground service; 200 seconds for background service. The ANR timeout period includes the app cold start, if necessary, and calls to onCreate(), onBind(), or onStartCommand().

To avoid execute service ANRs, follow these general best practices:

  • Make sure that app startup is fast, since it's counted in the ANR timeout if the app is started to run the service component.
  • Make sure that the service's onCreate(), onStartCommand(), and onBind() methods are fast.
  • Avoid running any slow or blocking operations on the main thread from other components; these operations can prevent a service from starting quickly.

Common causes

The following table lists common causes of execute service ANRs and suggested fixes.

Cause What Suggested fix
Slow app startup The app takes too long to perform a cold start. Optimize slow app start.
Slow onCreate(), onStartCommand(), or onBind() The service component's onCreate(), onStartCommand(), or onBind() method takes too long to execute on the main thread. Optimize slow code. Move slow operations off the critical path where possible.
Not scheduled (main thread blocked before onStart()) The app's main thread is blocked by another component before the service can be started. Move other component's work off the main thread. Optimize other component's blocking code.

How to debug

From the cluster signature and ANR report in Google Play Console or Firebase Crashlytics, you can often determine the cause of the ANR based on what the main thread is doing.

The following flow chart describes how to debug an execute service ANR.

Figure 6. How to debug an execute service ANR.

If you've determined that the execute service ANR is actionable, follow these steps to help resolve the issue:

  1. Find the service component class in the ANR signature. In Google Play Console, the service component class is shown in the ANR signature. In the following example ANR details, it's com.example.app/MyService.

    com.google.common.util.concurrent.Uninterruptibles.awaitUninterruptibly
    Executing service com.example.app/com.example.app.MyService
    
  2. Determine whether the slow or block operation is part of app startup, the service component, or elsewhere by checking for the following important function call(s) in the main threads.

    Function call(s) in main thread stacks What it means
    android.app.ActivityThread.handleBindApplication App was starting up, so the ANR was caused by slow app start.

    <ServiceClass>.onCreate()

    [...]

    android.app.ActivityThread.handleCreateService

    Service was being created, so the ANR was likely caused by slow onCreate() code.

    <ServiceClass>.onBind()

    [...]

    android.app.ActivityThread.handleBindService

    Service was being bound, so the ANR was likely caused by slow onBind() code.

    <ServiceClass>.onStartCommand()

    [...]

    android.app.ActivityThread.handleServiceArgs

    Service was being started, so the ANR was likely caused by slow onStartCommand() code.

    For example, if the onStartCommand() method in the MyService class is slow, the main threads will look like this:

    at com.example.app.MyService.onStartCommand(FooService.java:25)
    at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:4820)
    at android.app.ActivityThread.-$$Nest$mhandleServiceArgs(unavailable:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2289)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loopOnce(Looper.java:205)
    at android.os.Looper.loop(Looper.java:294)
    at android.app.ActivityThread.main(ActivityThread.java:8176)
    at java.lang.reflect.Method.invoke(Native method:0)
    

    Önemli işlev çağrılarının hiçbirini göremiyorsanız bunun birkaç nedeni daha vardır:

    • Hizmet çalışıyor veya kapanıyor. Bu, yığınların çok geç alındığı anlamına gelir. Bu durumda, ANR'yi yanlış pozitif olarak göz ardı edebilirsiniz.
    • Yayın alıcısı gibi farklı bir uygulama bileşeni çalışıyor olmalıdır. Bu durumda, ana iş parçacığı muhtemelen bu bileşende engellenerek hizmetin başlatılmasını engeller.
  3. Bir anahtar işlevi çağrısı görürseniz ve genel olarak ANR'nin nerede meydana geldiğini belirleyebiliyorsanız yavaş işlemi bulmak ve optimize etmek ya da kritik yoldan çıkarmak için ana iş parçacığı yığınlarının geri kalanını kontrol edin.

  4. Hizmetler hakkında daha fazla bilgi için aşağıdaki sayfalara bakın:

    İçerik sağlayıcı yanıt vermiyor

    Uzak içerik sağlayıcı, sorguya yanıt vermek için zaman aşımı süresinden uzun sürdüğünde ve sonlandırıldığında içerik sağlayıcı ANR'si oluşur.

    Varsayılan zaman aşımı süresi: İçerik sağlayıcı tarafından ContentProviderClient.setDetectNotResponding kullanılarak belirtilir. ANR zaman aşımı süresi, uzak bir içerik sağlayıcı sorgusunun çalıştırılacağı toplam süreyi içerir. Bu süreye, uzak uygulama çalışmıyorsa soğuk başlatma dahildir.

    İçerik sağlayıcı ANR'lerini önlemek için aşağıdaki en iyi uygulamaları izleyin:

    • Uygulama, içerik sağlayıcıyı çalıştırmaya başlarsa ANR zaman aşımında sayılacağından uygulama başlatılmasının hızlı olduğundan emin olun.
    • İçerik sağlayıcı sorgularının hızlı olduğundan emin olun.
    • Uygulamanın tüm bağlayıcı iş parçacıklarını engelleyebilecek çok sayıda eşzamanlı engelleme bağlayıcı çağrısı yapmayın.

    Yaygın nedenler

    Aşağıdaki tabloda, içerik sağlayıcı ANR'lerinin yaygın nedenleri ve önerilen düzeltmeler listelenmiştir.

    Neden Ne olur? Sinyal Önerilen düzeltme
    Yavaş içerik sağlayıcı sorgusu İçerik sağlayıcının yürütülmesi çok uzun sürüyor ya da engellendi. android.content.ContentProvider$Transport.query çerçevesi, bağlayıcı iş parçacığındadır. İçerik sağlayıcı sorgusunu optimize et. Bağlayıcı iş parçacığını neyin engellediğini öğrenin.
    Yavaş uygulama başlatma İçerik sağlayıcının uygulamasının başlatılması çok uzun sürüyor. ActivityThread.handleBindApplication çerçevesi, ana iş parçacığındadır. Uygulama başlatmayı optimize edin.
    Bağlayıcı iş parçacığının tükenmesi - tüm bağlayıcı iş parçacıkları meşgul Tüm bağlayıcı iş parçacıkları, başka eşzamanlı istekler sunmakla meşgul olduğundan içerik sağlayıcı bağlayıcı çağrısı çalışamaz. Uygulama başlatılmıyor, tüm bağlayıcı ileti dizileri meşgul ve içerik sağlayıcı çalışmıyor. Binder iş parçacıklarındaki yükü azaltın. Yani daha az eşzamanlı giden bağlayıcı çağrısı yapın veya gelen aramalarla ilgilenirken daha az iş yapın.

    Hata ayıklama

    Google Play Console veya Firebase Crashlytics'teki küme imzasını ve ANR raporunu kullanarak içerik sağlayıcı ANR'sinde hata ayıklamak için ana iş parçacığının ve bağlayıcı iş parçacıklarının ne yaptığına bakın.

    Aşağıdaki akış grafiğinde, içerik sağlayıcı ANR'sinde nasıl hata ayıklanacağı açıklanmaktadır:

    Şekil 7. İçerik sağlayıcı ANR'sinde hata ayıklama.

    Aşağıdaki kod snippet'i, yavaş içerik sağlayıcı sorgusu nedeniyle engellendiğinde bağlayıcı iş parçacığının nasıl göründüğünü gösterir. Bu durumda, içerik sağlayıcı sorgusu bir veritabanını açarken kilit beklemeyi bekler.

    binder:11300_2 (tid=13) Blocked
    
    Waiting for osm (0x01ab5df9) held by at com.google.common.base.Suppliers$NonSerializableMemoizingSupplier.get(Suppliers:182)
    at com.example.app.MyClass.blockingGetOpenDatabase(FooClass:171)
    [...]
    at com.example.app.MyContentProvider.query(MyContentProvider.java:915)
    at android.content.ContentProvider$Transport.query(ContentProvider.java:292)
    at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:107)
    at android.os.Binder.execTransactInternal(Binder.java:1339)
    at android.os.Binder.execTransact(Binder.java:1275)
    

    Aşağıdaki kod snippet'i, uygulamanın yavaş başlatılması nedeniyle engellendiğinde ana iş parçacığının nasıl göründüğünü gösterir. Bu durumda, hançerin başlatılması sırasındaki kilit çakışması nedeniyle uygulama yavaş başlar.

    main (tid=1) Blocked
    
    [...]
    at dagger.internal.DoubleCheck.get(DoubleCheck:51)
    - locked 0x0e33cd2c (a qsn)at dagger.internal.SetFactory.get(SetFactory:126)
    at com.myapp.Bar_Factory.get(Bar_Factory:38)
    [...]
    at com.example.app.MyApplication.onCreate(DocsApplication:203)
    at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1316)
    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6991)
    at android.app.ActivityThread.-$$Nest$mhandleBindApplication(unavailable:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2235)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loopOnce(Looper.java:205)
    at android.os.Looper.loop(Looper.java:294)
    at android.app.ActivityThread.main(ActivityThread.java:8170)
    at java.lang.reflect.Method.invoke(Native method:0)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
    

    Yavaş iş yanıtı

    Uygulamanın JobService.onStartJob() veya JobService.onStopJob() komutuna yanıt vermesi çok uzun sürer ya da JobService.setNotification() kullanarak bildirim sağlaması çok uzun sürerse yavaş iş yanıtı ANR'si oluşur. Bu, uygulamanın ana iş parçacığının başka bir şey yapmasının engellendiğini gösterir.

    Sorun JobService.onStartJob() veya JobService.onStopJob() ile ilgiliyse ana iş parçacığında neler olup bittiğini kontrol edin. Sorun JobService.setNotification() ile ilgiliyse mümkün olan en kısa sürede çağırdığınızdan emin olun. Bildirimi göndermeden önce çok fazla işlem yapmayın.

    Gizemli ANR'ler

    Bazen bir ANR'nin neden meydana geldiği net değildir veya küme imzası ve ANR raporunda hata ayıklamak için yeterli bilgi bulunmaz. Bu durumlarda, ANR'nin uygulanabilir olup olmadığını belirlemek için atabileceğiniz bazı adımlar vardır.

    Mesaj sırası boşta veya NativePollBefore'ta

    Yığınlarda android.os.MessageQueue.nativePollOnce çerçevesini görürseniz bu, genellikle yanıt vermediği şüpheli iş parçacığının gerçekten boşta olduğunu ve döngü aracı mesajlarını beklediğini gösterir. Google Play Console'da ANR ayrıntıları şöyle görünür:

    Native method - android.os.MessageQueue.nativePollOnce
    Executing service com.example.app/com.example.app.MyService
    

    Örneğin, ana iş parçacığı boştaysa yığınlar şu şekilde görünür:

    "main" tid=1 NativeMain threadIdle
    
    #00  pc 0x00000000000d8b38  /apex/com.android.runtime/lib64/bionic/libc.so (__epoll_pwait+8)
    #01  pc 0x0000000000019d88  /system/lib64/libutils.so (android::Looper::pollInner(int)+184)
    #02  pc 0x0000000000019c68  /system/lib64/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+112)
    #03  pc 0x000000000011409c  /system/lib64/libandroid_runtime.so (android::android_os_MessageQueue_nativePollOnce(_JNIEnv*, _jobject*, long, int)+44)
    at android.os.MessageQueue.nativePollOnce (Native method)
    at android.os.MessageQueue.next (MessageQueue.java:339)  at android.os.Looper.loop (Looper.java:208)
    at android.app.ActivityThread.main (ActivityThread.java:8192)
    at java.lang.reflect.Method.invoke (Native method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:626)
    at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1015)
    

    Yanıt vermediğinden şüphelenilen ileti dizisinin boşta olmasının birkaç nedeni vardır:

    • Geç yığın dökümü. İş parçacığı, ANR'nin tetiklenmesi ile yığınların dökümü arasındaki kısa dönemde kurtarıldı. Android 13'te Pixel'lerdeki gecikme yaklaşık 100 ms'dir ancak 1 saniyeyi aşabilir. Android 14'te Pixel'lerdeki gecikme genellikle 10 ms'nin altındadır.
    • İleti dizisinin yanlış ilişkilendirilmesi. ANR imzasını oluşturmak için kullanılan iş parçacığı, ANR'ye neden olan asıl yanıt vermeyen iş parçacığı değildi. Bu durumda, ANR'nin aşağıdaki türlerden biri olup olmadığını belirlemeye çalışın:
    • Sistem genelinde sorun. İşlem, yoğun sistem yükü veya sistem sunucusundaki bir sorun nedeniyle planlanmamıştır.

    Yığın çerçevesi yok

    Bazı ANR raporları, ANR'li yığınları içermez. Bu da ANR raporu oluşturulurken yığın dökümünün başarısız olduğu anlamına gelir. Yığın karelerinin eksik olmasının birkaç nedeni olabilir:

    • Not yığınının alınması çok uzun sürer ve zaman aşımına uğrar.
    • Süreç, yığınlar alınmadan önce ölmüş veya sonlandırılmıştır.
    [...]
    
    --- CriticalEventLog ---
    capacity: 20
    timestamp_ms: 1666030897753
    window_ms: 300000
    
    libdebuggerd_client: failed to read status response from tombstoned: timeout reached?
    
    ----- Waiting Channels: pid 7068 at 2022-10-18 02:21:37.<US_SOCIAL_SECURITY_NUMBER>+0800 -----
    
    [...]
    

    Yığın çerçeveleri olmayan ANR'lerle ilgili olarak küme imzası veya ANR raporu kullanılamaz. Bir sorun yeterince büyükse genellikle yığın çerçevelerinin bulunduğu kendi kümesi olacağından hata ayıklamak için uygulamanın diğer kümelerine bakın. Diğer bir seçenek de Perfetto izlerine bakmaktır.

    Bilinen sorunlar

    ANR tetikleyicisi olmadan önce yayın işlemeyi tamamlamak amacıyla uygulamanızın işleminde bir zamanlayıcı tutmak, sistemin ANR'leri eşzamansız şekilde izlemesi nedeniyle düzgün çalışmayabilir.