自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)
公开问题
从这些跟踪信息中我可以看到,每次服务调用期间,系统似乎都被卡住了。电话服务。有什么解释为什么会这样吗? 我希望如果执行时间>〜10sec,就会发生ANR,所以一定有死锁吗? 可能的解决方案是将所有事件处理都移到另一个线程,但这不能解释问题,我希望异步执行也会被卡住?
编辑:可笑的是,所有这些ANR的标题均为:
意向广播{act = android.intent.action.SCREEN_OFF flg = 0x50200010}
答案 0 :(得分:1)
尝试以下操作,我发现了类似的结算错误堆栈:
请勿在 MyPhoneStateObserver 或任何广播接收器中拨打任何网络电话,读取或写入文件,操作数据库等。您可能正在调用某种阻塞应用程序线程的方法。我建议从单独的线程中调用这类方法。
请问为什么会发生这种情况? 我认为您应该仔细检查您的 MyPhoneStateObserver 类,我想您正在进行一些网络调用,读取或写入文件,操作数据库或任何操作应该在单独的线程中完成。您在此类或重写方法中实现的操作/代码尝试在单独的线程中进行操作。
我希望如果执行时间>〜10秒,那么就会发生ANR,因此必须存在死锁?当主线程被阻塞几次时,就会发生ANR。具体来说,活动中为5秒,广播接收器中为10秒,服务中为20秒。
可能的解决方案是将所有事件处理移至另一个线程,但这不能解释问题,并且我希望异步执行也会被卡住?是的,您是对的将您的代码移动到另一个线程。但是我认为asysnctask不能在这里工作,在服务或后台侦听器中,我相信您需要使用线程。
答案 1 :(得分:0)
根据您的错误代码。
意图广播{act = android.intent.action.SCREEN_OFF flg = 0x50200010}
请尝试使用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的问题。
希望这会有所帮助。