ANR при вызове системной службы (например, службы телефонии) - PullRequest
0 голосов
/ 19 октября 2018

, начиная с Android 8, в консоли разработчика Google Play сообщается об увеличении количества ANR.Общим для всех них является то, что ANR не имеет прямого отношения к моему коду, а всегда относится к системным вызовам.См. Следующие примеры:

Пример 1:

"main" prio=5 tid=1 Native
  | group="main" sCount=1 dsCount=0 flags=1 obj=0x73798b10 self=0x73186a3a00
  | sysTid=12505 nice=0 cgrp=default sched=0/0 handle=0x731d5c49b0
  | state=S schedstat=( 28971945984 27609449667 173830 ) utm=1926 stm=970 core=1 HZ=100
  | stack=0x7fd4e3d000-0x7fd4e3f000 stackSize=8MB
  | held mutexes=
  #00  pc 000000000001db2c  /system/lib64/libc.so (syscall+28)
  #01  pc 00000000000e1f30  /system/lib64/libart.so (_ZN3art17ConditionVariable16WaitHoldingLocksEPNS_6ThreadE+152)
  #02  pc 00000000004e21a4  /system/lib64/libart.so (_ZN3artL12GoToRunnableEPNS_6ThreadE+440)
  #03  pc 00000000004e1fa4  /system/lib64/libart.so (_ZN3art12JniMethodEndEjPNS_6ThreadE+28)
  #04  pc 0000000000991b3c  /system/framework/arm64/boot-framework.oat (Java_android_os_BinderProxy_transactNative__ILandroid_os_Parcel_2Landroid_os_Parcel_2I+220)
  at android.os.BinderProxy.transactNative (Native method)
  at android.os.BinderProxy.transact (Binder.java:761)
  at android.os.ServiceManagerProxy.getService (ServiceManagerNative.java:123)
  at android.os.ServiceManager.getService (ServiceManager.java:66)
  at android.telephony.SubscriptionManager.getPhoneId (SubscriptionManager.java:953)
  at android.telephony.TelephonyManager.getNetworkOperatorName (TelephonyManager.java:1693)
  at android.telephony.TelephonyManager.getNetworkOperatorName (TelephonyManager.java:1679)

    [...]

  at com.xx.x.v$1.onSignalStrengthsChanged (MyPhoneStateObserver.java:99)
  at android.telephony.PhoneStateListener$1.handleMessage (PhoneStateListener.java:349)
  at android.os.Handler.dispatchMessage (Handler.java:105)
  at android.os.Looper.loop (Looper.java:164)
  at android.app.ActivityThread.main (ActivityThread.java:6944)
  at java.lang.reflect.Method.invoke (Native method)
  at com.android.internal.os.Zygote$MethodAndArgsCaller.run (Zygote.java:327)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1374)

Пример 2:

"main" prio=5 tid=1 Native
  | group="main" sCount=1 dsCount=0 flags=1 obj=0x737b5bb0 self=0x7e0f4a3a00
  | sysTid=24248 nice=0 cgrp=default sched=0/0 handle=0x7e144ca9b0
  | state=S schedstat=( 36923767919 38940772860 261304 ) utm=2358 stm=1334 core=7 HZ=100
  | stack=0x7fdc8c2000-0x7fdc8c4000 stackSize=8MB
  | held mutexes=
  #00  pc 000000000001da2c  /system/lib64/libc.so (syscall+28)
  #01  pc 00000000000e1ee4  /system/lib64/libart.so (_ZN3art17ConditionVariable16WaitHoldingLocksEPNS_6ThreadE+152)
  #02  pc 00000000004e35c8  /system/lib64/libart.so (_ZN3artL12GoToRunnableEPNS_6ThreadE+440)
  #03  pc 00000000004e33c8  /system/lib64/libart.so (_ZN3art12JniMethodEndEjPNS_6ThreadE+28)
  #04  pc 000000000098b14c  /system/framework/arm64/boot-framework.oat (Java_android_os_BinderProxy_transactNative__ILandroid_os_Parcel_2Landroid_os_Parcel_2I+220)
  at android.os.BinderProxy.transactNative (Native method)
  at android.os.BinderProxy.transact (Binder.java:751)
  at android.net.INetworkStatsService$Stub$Proxy.getMobileIfaces (INetworkStatsService.java:318)

     [...]

  at com.xx.(MyPhoneStateObserver.java)
  at android.telephony.PhoneStateListener$1.handleMessage (PhoneStateListener.java:331)
  at android.os.Handler.dispatchMessage (Handler.java:108)
  at android.os.Looper.loop (Looper.java:166)
  at android.app.ActivityThread.main (ActivityThread.java:7425)
  at java.lang.reflect.Method.invoke (Native method)
  at com.android.internal.os.Zygote$MethodAndArgsCaller.run (Zygote.java:245)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:921)

Открытые вопросы

ЧтоИз этих следов я вижу, что каждый раз, когда кажется, что система застревает во время служебного вызова, например, в телефонную службу.Есть ли объяснение, почему это происходит?Я ожидаю, что ANR произойдет, если время выполнения> 10 секунд, поэтому должен быть тупик?Возможным решением было бы перенести всю обработку событий в другой поток, но это не объясняет проблему, и я ожидаю, что асинхронное выполнение также будет зависать?

Редактировать: Самое смешное, что все эти ANR озаглавлены:

Трансляция намерений {act = android.intent.action.SCREEN_OFF flg= 0x50200010}

Ответы [ 2 ]

0 голосов
/ 29 октября 2018

Попробуйте выполнить следующее: я нашел похожий стек ошибок для выставления счетов:

Не вызывайте никаких сетевых вызовов, чтения или записи файлов, работающих баз данных и т. Д. В вашем MyPhoneStateObserver или любой вещательный приемник.Возможно, вы вызываете какой-то метод, который блокирует поток приложения.Я бы посоветовал вызывать такие методы из отдельного потока .

Есть ли какое-либо объяснение, почему это происходит? Я думаю, вам следует дважды проверить свой MyPhoneStateObserver класс, я полагаю, вы делаете некоторые сетевые вызовы, чтение или запись файлов, рабочие базы данных или любая операция, которая должна выполняться в отдельном потоке.Операции / код, которые вы реализовали в этом классе или переопределенном методе, пытаются сделать это в отдельном потоке.

Я ожидаю, что ANR произойдет, если время выполнения> 10 секунд, поэтому должна быть тупиковая ситуация? ANR возникает, когда основной поток заблокирован на некоторое время.В частности, 5 секунд в Activity, 10 секунд в BroadcastReceiver и 20 секунд в Service.

Возможным решением будет перенести всю обработку событий в другой поток, но это не объясняет проблемуи я ожидаю, что асинхронное выполнение также зависнет? Да, вы правы, вы должны перенести свой код в другой поток.Но я не думаю, что asysnctask будет работать здесь, в сервисах или фоновых слушателях, я полагаю, вам нужно будет использовать thread

0 голосов
/ 24 октября 2018

Основываясь на своем коде ошибки.

Трансляция намерений {act = android.intent.action.SCREEN_OFF flg = 0x50200010}

Пожалуйста, попробуйте использовать Wakelock.Это будет препятствовать тому, чтобы система отключила процесс ваших приложений до тех пор, пока вы не отпустите блокировку.

Вы можете приобрести wakelock следующим образом

PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
    "MyApp::MyWakelockTag");
wakeLock.acquire();

Пожалуйста, обратитесь к документации для получения более подробной информации.https://developer.android.com/training/scheduling/wakelock#java

Также обратитесь к https://developer.android.com/about/versions/oreo/background Как указано в комментариях, система Android пытается оптимизировать ресурсы, и это может быть проблемой, которая вызывает ANR в вашем случае.

Надеждаэто помогает.

...