Ric*_* Ai 8 android broadcastreceiver
07-22 04:38:07.933 1579 3338 E JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 352)
07-22 04:38:07.933 1579 3338 W BroadcastQueue: Can't deliver broadcast to com.android.systemui (pid 2160). Crashing it.
07-22 04:38:07.934 1579 3338 W BroadcastQueue: Failure sending broadcast Intent { act=android.intent.action.TIME_TICK flg=0x50000014 (has extras) }
07-22 04:38:07.934 1579 3338 W BroadcastQueue: android.os.DeadObjectException: Transaction failed on small parcel; remote process probably died
07-22 04:38:07.934 1579 3338 W BroadcastQueue: at android.os.BinderProxy.transactNative(Native Method)
07-22 04:38:07.934 1579 3338 W BroadcastQueue: at android.os.BinderProxy.transact(Binder.java:618)
07-22 04:38:07.934 1579 3338 W BroadcastQueue: at android.app.ApplicationThreadProxy.scheduleRegisteredReceiver(ApplicationThreadNative.java:1211)
07-22 04:38:07.934 1579 3338 W BroadcastQueue: at com.android.server.am.BroadcastQueue.performReceiveLocked(BroadcastQueue.java:489)
07-22 04:38:07.934 1579 3338 W BroadcastQueue: at com.android.server.am.BroadcastQueue.deliverToRegisteredReceiverLocked(BroadcastQueue.java:702)
07-22 04:38:07.934 1579 3338 W BroadcastQueue: at com.android.server.am.BroadcastQueue.processNextBroadcast(BroadcastQueue.java:1002)
07-22 04:38:07.934 1579 3338 W BroadcastQueue: at com.android.server.am.BroadcastQueue.processNextBroadcast(BroadcastQueue.java:799)
07-22 04:38:07.934 1579 3338 W BroadcastQueue: at com.android.server.am.ActivityManagerService.finishReceiver(ActivityManagerService.java:19153)
07-22 04:38:07.934 1579 3338 W BroadcastQueue: at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:528)
07-22 04:38:07.934 1579 3338 W BroadcastQueue: at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2909)
07-22 04:38:07.934 1579 3338 W BroadcastQueue: at android.os.Binder.execTransact(Binder.java:565)
07-22 04:38:07.937 2160 2160 D AndroidRuntime: Shutting down VM
07-22 04:38:07.953 2160 2625 E JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 136)
--------- beginning of crash
07-22 04:38:07.972 2160 2160 E AndroidRuntime: FATAL EXCEPTION: main
07-22 04:38:07.972 2160 2160 E AndroidRuntime: Process: com.android.systemui, PID: 2160
07-22 04:38:07.972 2160 2160 E AndroidRuntime: android.app.RemoteServiceException: can't deliver broadcast
07-22 04:38:07.972 2160 2160 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1690)
07-22 04:38:07.972 2160 2160 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:102)
07-22 04:38:07.972 2160 2160 E AndroidRuntime: at android.os.Looper.loop(Looper.java:160)
07-22 04:38:07.972 2160 2160 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6252)
07-22 04:38:07.972 2160 2160 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
07-22 04:38:07.972 2160 2160 E AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:898)
07-22 04:38:07.972 2160 2160 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:788)
Run Code Online (Sandbox Code Playgroud)
该错误发生在BroadcastQueue类中,当它通过Binder调用scheduleRegisteredReceiver时,DeadObjectException抛出.就像LOG所说:小包裹上的交易失败; 远程进程可能已经死了,但是为什么RuntimeException会抛出com.android.systemui进程,如果它已经死了?
基本上,艾瑞克对自己问题的回答都是正确的,但这是一个现实世界的例子:
如果您的应用程序创建并注册了一大堆BroadcastReceiver实例,所有实例都侦听相同的操作(可能是由于应用程序中的泄漏或错误),那么系统进程中的 ActivityManagerService 将为每个注册实例调用android.app.IApplicationThread方法scheduleRegisteredReceiver。请注意,此特定方法的活页夹事务是oneway。由于它是oneway每个调用将立即返回,并且在每个事务完成之前对绑定器驱动程序的调用将非常快速地发生,因此有效地并行运行它们。
假设您的应用程序中有 100 个接收器,并且接收到的广播包含 20 KiB 的数据。现在,您有 2 MiB 尝试通过活页夹驱动程序,但由于 1 MiB 的限制,它将失败。
在内核日志中您将看到:
binder: 1282:1298 transaction failed 29201/-28, size 28052-8 line 3072
Run Code Online (Sandbox Code Playgroud)
因此要小心泄漏BroadcastReceiver并小心oneway活页夹交易。请注意,显然 AIDL 文件可能不会声明方法oneway,但如果 AIDL 编译器认为这是可能的,那么最终可能会这样。
我终于找到了根本原因,它发生在绑定程序内核中。
到目前为止,我发现了导致DeadObjectException抛出到BroadcastQueue中并导致应用程序中ActivityThread抛出RemoteServiceException之后的两个原因:
相关代码如下所示:
kernel/msm-4.4/drivers/android/binder_alloc.c
290 if (is_async &&
291 alloc->free_async_space < size + sizeof(struct binder_buffer)) {
292 binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC,
293 "%d: binder_alloc_buf size %zd failed, no async space left\n",
294 alloc->pid, size);
295 eret = ERR_PTR(-ENOSPC);
296 goto error_unlock;
297 }
Run Code Online (Sandbox Code Playgroud)
因此,这不会“破坏系统的稳定性”。它只会影响应用程序本身。
该错误可以通过以下步骤触发:
这是代码:
kernel/msm-4.4/drivers/android/binder_alloc.c
315 if (best_fit == NULL) {
...
341 pr_err("%d: binder_alloc_buf size %zd failed, no address space\n",
342 alloc->pid, size);
343 pr_err("allocated: %zd (num: %zd largest: %zd), free: %zd (num: %zd largest: %zd)\n",
344 total_alloc_size, allocated_buffers, largest_alloc_size,
345 total_free_size, free_buffers, largest_free_size);
346 eret = ERR_PTR(-ENOSPC);
347 goto error_unlock;
348 }
Run Code Online (Sandbox Code Playgroud)
总之,即使应用程序进程尚未终止,也可能引发DeadObjectException。
根本原因很可能是因为应用程序具有完整的绑定程序缓冲区,并且不影响系统。
因此,我认为在BroadcastQueue中捕获DeadObjectException之后不必使应用程序崩溃。
| 归档时间: |
|
| 查看次数: |
7786 次 |
| 最近记录: |