Unity ANR'leri çeşitli nedenlerden kaynaklanır. En yaygın ANR'lerin nedeni hatalı iletişim ve iletişim sorunları.
Web Görünümü
WebView
, web sayfalarını gösteren bir Android sınıfıdır. Üçüncü taraf
SDK'lar (ör. reklamlar), dinamik web içeriğini görüntülemek için WebView
kullanır
UnityPlayerActivity
dışındaki etkinliklerde. ANR'ler, üçüncü tarafın
SDK'lar, WebView
politikasını kötüye kullanıyor.
Yığın izi
Yığın izleme, ANR'nin nedenini anlamak için başvuracağınız ilk başvurudur.
/data/app/~~p-0ksfCD6bF6Sdq6kpVePg==/com.google.android.webview-5YQZOqKbbqp-uoLY6WYnTw==/base.apk!libmonochrome.so
at J.N.Mhc_M_H$ (Native method)
at org.chromium.components.viz.service.frame_sinks.ExternalBeginFrameSourceAndroid.doFrame (chromium-TrichromeWebViewGoogle.aab-stable-579013831:60)
at android.view.Choreographer$CallbackRecord.run (Choreographer.java:1054)
at android.view.Choreographer.doCallbacks (Choreographer.java:878)
at android.view.Choreographer.doFrame (Choreographer.java:807)
at android.view.Choreographer$FrameDisplayEventReceiver.run (Choreographer.java:1041)
at android.os.Handler.handleCallback (Handler.java:938)
at android.os.Handler.dispatchMessage (Handler.java:99)
at android.os.Looper.loop (Looper.java:223)
at android.app.ActivityThread.main (ActivityThread.java:7721)
at java.lang.reflect.Method.invoke (Native method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:952)
Şekil 1. futex beklemeden kaynaklanan ANR yığın izlemesi.
Neden
Şu ana kadar bu sorunun temel nedeni belirsiz. Bazı olası nedenler şunlardır:
- Kötü reklam uygulaması.
- Kullanıcı güncelleme yapmayı tercih etmemiş olabileceğinden eski bir
WebView
sürümü otomatik olarak yüklenir. - Sistem kaynaklarının (CPU, GPU vb.) yüksek oranda kullanımı. Bu da çok fazla profil çıkarma.
- Gölgelendirme derlemesi kilitleniyor ve bu da
içerik uyumsuz bir gölgelendiriciye sahip veya kullanıcının eski bir
WebView
sahibi var sürümü yüklendi.
Çözüm
- Hangi içerik türünün
WebView
tarafından engellenmesine neden olduğunu bulmak için ana iş parçacığı, bir web sayfası yüklendiğinde, görüntülendiğinde emin olun.- Geri izleme veya Crashlytics'i kullanabilirsiniz raporlama hizmetleridir.
- Ardından, verileri analiz edip sorunu bulduktan sonra rahatsız edici reklam sağlayıcıları.
- Sorunun bellekle ilgili olmadığından emin olmak için bellek günlüklerini ekleyin.
- Google Play'den
WebView
öğesini güncellemesi için kullanıcıyı uyarın. Android 5.0'dan (API düzeyi 21) ve sonraki sürümler içinWebView
, bir APK'ya taşındı. Bu nedenle, Android platformundan ayrı olarak güncellenir.WebView
sürümünün hangisi olduğunu öğrenmek için bir cihazda kullanılıyorsa Ayarlar > Uygulamalar > Android Sistemi WebView'u tıklayın ve sayfanın alt kısmından sürüme bakın.
Unity duraklatma
UnityPlayerActivity
bir onPause()
çağrısı aldığında aşağıdaki zincir
işlemlerin başlangıcı:
UnityPlayerActivity
, Unity çalışma zamanı motoruna etkinliğin duraklatıldı.- Unity, şunu uygulayan her
MonoBehaviour
OnApplicationPause
etkinliği. - Unity, ses çalma, oluşturma ve yayınlama gibi bileşenleri ve modülleri oyun döngüsü ve animasyon.
- Hem
Unity Android Player
(UAP) hem de motorun UAP, motorun durması için 4 saniye bekler. - Bu işlem 5 saniyeden uzun sürerse sistem bir ANR tetikler.
Yığın izi
"main" tid=1 Timed Waiting
jdk.internal.misc.Unsafe.park (Native method)
java.util.concurrent.locks.LockSupport.parkNanos (LockSupport.java:234)
java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedNanos (AbstractQueuedSynchronizer.java:1079)
java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos (AbstractQueuedSynchronizer.java:1369)
java.util.concurrent.Semaphore.tryAcquire (Semaphore.java:415)
com.unity3d.player.UnityPlayer.pauseUnity (UnityPlayer.java:833)
com.unity3d.player.UnityPlayer.pause (UnityPlayer.java:796)
com.unity3d.player.UnityPlayerActivity.onPause (UnityPlayerActivity.java:117)
android.app.Activity.performPause (Activity.java:8517)
android.app.Instrumentation.callActivityOnPause (Instrumentation.java:1618)
android.app.ActivityThread.performPauseActivityIfNeeded (ActivityThread.java:5061)
android.app.ActivityThread.performPauseActivity (ActivityThread.java:5022)
android.app.ActivityThread.handlePauseActivity (ActivityThread.java:4974)
android.app.servertransaction.PauseActivityItem.execute (PauseActivityItem.java:48)
android.app.servertransaction.ActivityTransactionItem.execute (ActivityTransactionItem.java:45)
android.app.servertransaction.TransactionExecutor.executeLifecycleState (TransactionExecutor.java:179)
android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.java:97)
android.app.ActivityThread$H.handleMessage (ActivityThread.java:2303)
android.os.Handler.dispatchMessage (Handler.java:106)
android.os.Looper.loopOnce (Looper.java:201)
android.os.Looper.loop (Looper.java:288)
android.app.ActivityThread.main (ActivityThread.java:7884)
java.lang.reflect.Method.invoke (Native method)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:548)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:936)
Şekil 3. Hiç yayınlanmayan bir semaforun neden olduğu ANR.
Çözüm
C# oyun kodunuzun devam ettirebilirsiniz.
- Oyununuzun profilini çıkarın ve
OnApplicationPause
cihazının pahalı bir cihaz olup olmadığını kontrol edin. işlemidir.Stopwatch
kullanabilirsiniz. - G/Ç işlemlerinden veya eşzamanlı ağ isteklerinden kaçının.
- İşlemleri başka bir
Thread
'e taşımak içinTask
. Unity 2023.1, basitleştirilmiş bir C# kullanan eşzamansız programlama modeliasync
veawait
anahtar kelime.
UnitySendMessage engellendi
Java Unity eklentileri ve SDK'ları, JNI kullanarak C# oyun katmanına veri gönderir. Ancak bu iletişim, senkronizasyon rutini gibi, kilit çakışması nedeniyle ANR'ye neden oluyor.
Yığın izi
Şekil 4'teki ANR, C# kodunda Java eklentisi. Unity motoru, bir Öncelikli Olmayan Devralma komutunun doğru yürütülmesini sağlamak için
libc.so NonPI::MutexLockWithTimeout(pthread_mutex_internal_t*, bool, timespec const*) + 604
com.unity3d.player.UnityPlayer.nativeUnitySendMessage (Native method)
com.unity3d.player.UnityPlayer.UnitySendMessage (UnityPlayer.java:665)
Şekil 4. Kilit anlaşmazlığından kaynaklanan ANR.
Neden
Sorun, uygulama aynı anda birkaç iletinin gönderilmesi devam ettirilir. Mesajlar oyun sırasında gönderilemediği için sıraya alındı arka planda. emin olun.
Duraklama döneminde oyununuzun bilgileri genellikle şurada saklanır: sunucu; Örneğin, bir oyuncunun oyundaki konumunu kaydedersiniz. oyun devam ettiğinde aynı yere dönebilir.
Bu iş yükü, kendi iş yükünü oluşturan diğer üçüncü taraf kodlarıyla birlikte kullanıldığında cihaz kaynaklarında, özellikle de ana iş parçacığında aşırı yüklenmeye yol açabilir. Ana iş parçacığı bir uygulamanın kullanıcı arayüzünü çalıştırır ve genellikle ANR'lerin ana konumudur. Dolayısıyla, ana iş parçacığında ek iş yükü, ANR olasılığını artırır.
Çözüm
Uygulama duraklatması sırasında tüm kod işlemlerinizin gerekli olduğundan emin olun veya kullanıcının durumunu yerel cihazınızın belleğine kaydetmeyi deneyin. Tabii ki bu işlemleri duraklatma süresinin dışında da tamamlayıp tamamlayamayacağınızı belirleyin.
Birkaç yaklaşım:
- İletiyi işleyen C# işlemini ileti dizisine taşıma
diğerlerini görebilirsiniz.
- Kodunuz Unity'nin ana iş parçacığı bağlamına bağlı değilse
Mesaj yerine iletişim için
Task
.
- Kodunuz Unity'nin ana iş parçacığı bağlamına bağlı değilse
Mesaj yerine iletişim için
- Oyun duraklatıldığında eklentinizden birden fazla mesaj göndermeyin.
- Oyun arka plandayken motor mesaj gönderemez.
- Son veri durumunu yalnızca oyununuzu etkilemiyorsa gönderin işlevi görür.
Yönlendiren'i yükleyin
Play Install Referrer, bir Kullanıcı bir reklamı tıkladığında. Android'e özel bir reklam izleme kimliğidir. Bir kez yüklendiğinde uygulama, yükleme yönlendirenini ilişkilendirme iş ortağına gönderir. Bu da kaynağı yüklemeyle eşleştirir (dönüşümü ilişkilendirme).
Yığın izi
Şekil 5'te, aşağıdakileri yapmak için Facebook SDK'sını kullanan bir oyuna ait ANR yığın izlemesi (stack trace) gösterilmektedir almalarını isteyebilirsiniz.
Neden
ANR, yavaş bir bağlayıcı çağrısından kaynaklandı. Ancak, sorunun temel nedeni erişimi olmadan belirlenir.
Çözüm
Bu tür sorunları çözmek için SDK geliştiricisiyle veya potansiyel bir çözüm ararken, yeni bir çözüm olup olmadığını veya SDK'nın ANR'yi diğer kullanıcılar için çözdüğünü ve hatta küçük bir stratejik düşünmeyi kullanacaksınız.
Google, kullanım verilerini birleştiren bir SDK Dizini sayfası sağlar kod algılama üzerinden toplanan bilgilerle Google Play uygulamalarından gelen karar verirken size yol gösterecek olan özellikleri ve sinyalleri kullanmaya devam edebilir veya uygulamanızdan kaldırabilirsiniz.
Ek kaynaklar
ANR'ler hakkında daha fazla bilgi edinmek için aşağıdaki kaynaklara bakın:
- ANR'lerde hata ayıklama — Android oyun geliştirme
- ANR'ler: Uygulama kalitesi