AIDL beginBroadcast() called while already in a broadcast问题分析及源码解析

在写aidl 逻辑的时候遇到了beginBroadcast() called while already in a broadcast 意思是已经在广播中调用了

源码:

    public int beginBroadcast() {
        synchronized (mCallbacks) {
            if (mBroadcastCount > 0) {
                throw new IllegalStateException(
                        "beginBroadcast() called while already in a broadcast");
            }
            
            final int N = mBroadcastCount = mCallbacks.size();
            if (N <= 0) {
                return 0;
            }
            Object[] active = mActiveBroadcast;
            if (active == null || active.length < N) {
                mActiveBroadcast = active = new Object[N];
            }
            for (int i=0; i<N; i++) {
                active[i] = mCallbacks.valueAt(i);
            }
            return N;
        }
    }

也查询其他帖子,共两类观点:
1.是因为多个进程clieng同时请求server,其中一个任务阻塞,导致server接收任务的整个通道阻塞,所以会报异常。个人不认同这种观点,是因为beginBroadcast内部进行了锁处理。有锁就意味着本身就有多个任务要处理,remoteCallList本身就是为了处理client的callback的,所以不会再让你处理子任务之间线程关系。
2.还有一个观点是,上次的任务没有调用finishBroadcast(),所以报异常。个人赞同第二种。翻阅源码我们可以看到对mBroadcastCount该字段进行判断,这个字段由mCallbacks容器的size决定。而finishBroadcast方法也有锁,而且锁的对象是当前的容器mCallbacks,所以判断beginBroadcast()和finishBroadcast()是配套使用的。那为什么会出现该问题。
个人猜测:
是因为server在回调client的方法时可能发现异常,导致没有触发finishBroadcast(),所以导致资源没有回收,才会出现问题,建议大家好好review代码。

在finally处理finishBroadcast()方法

   public static void sendMsgToClient(String packageName, String json) {
        try {
            int i = remoteCallbackList.beginBroadcast();
            Log.d(TAG, "------------------sendMsgToClient: (i="+i+") json:" + json+"  packageName:"+packageName);
            while (i > 0) {
                i--;
                String cookie = (String) remoteCallbackList.getBroadcastCookie(i);
                if (packageName.equals(cookie)) {
                    ClientCallback callback = remoteCallbackList.getBroadcastItem(i);
                    callback.onServerAction(json);
                }
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }finally {
            remoteCallbackList.finishBroadcast();
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值