java.lang.RuntimeException: Error receiving broadcast Intent { act=android.intent.action.USER_SWITCHED flg=0x50000010 (has extras) } in com.android.server.notification.NotificationManagerService$3@b5a472d
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:1134)
at android.os.Handler.handleCallback(Handler.java:754)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:160)
at com.android.server.SystemServer.run(SystemServer.java:355)
at com.android.server.SystemServer.main(SystemServer.java:220)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:874)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:764)
Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.get(ArrayList.java:411)
at com.android.server.notification.NotificationManagerService$NotificationRankers.onUserSwitched(NotificationManagerService.java:3912)
at com.android.server.notification.NotificationManagerService$3.onReceive(NotificationManagerService.java:804)
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:1124)
... 8 more
该问题是n上的google原生问题,问题根源:
NotificationManagerService.java中,NotificationRankers 继承了 MangerServices
@Override public void onUserSwitched(int user) { synchronized (mMutex) { int i = mServices.size()-1; while (i --> 0) { final ManagedServiceInfo info = mServices.get(i); unregisterService(info.service, info.userid); } } registerRanker(); }
在 while 循环中,调用了unregisterService
public void unregisterService(IInterface service, int userid) { checkNotNull(service); // no need to check permissions; if your service binder is in the list, // that's proof that you had permission to add it in the first place unregisterServiceImpl(service, userid); }
private void unregisterServiceImpl(IInterface service, int userid) { ManagedServiceInfo info = removeServiceImpl(service, userid); if (info != null && info.connection != null && !info.isGuest(this)) { mContext.unbindService(info.connection); } }
/** * Removes a service from the list but does not unbind * * @return the removed service. */ private ManagedServiceInfo removeServiceImpl(IInterface service, final int userid) { if (DEBUG) Slog.d(TAG, "removeServiceImpl service=" + service + " u=" + userid); ManagedServiceInfo serviceInfo = null; synchronized (mMutex) { final int N = mServices.size(); for (int i = N - 1; i >= 0; i--) { final ManagedServiceInfo info = mServices.get(i); if (info.service.asBinder() == service.asBinder() && info.userid == userid) { if (DEBUG) Slog.d(TAG, "Removing active service " + info.component); serviceInfo = removeServiceLocked(i); } } } return serviceInfo; } private ManagedServiceInfo removeServiceLocked(int i) { final ManagedServiceInfo info = mServices.remove(i); onServiceRemovedLocked(info); return info; }
这里的for循环会删去MangedServiceInfo,导致最外层的while循环i计数错误。当mService为空以后,报出数组越界,导致手机重启
本文分析了一个导致Android设备在用户切换时出现崩溃并重启的问题。问题出现在NotificationManagerService中,由于循环删除服务信息时的计数错误,导致数组越界异常。文章详细介绍了问题发生的代码路径及异常原因。

1837

被折叠的 条评论
为什么被折叠?



