[framework]android - 四大组件 - 动态广播的注册和收发原理

在安卓中,广播的接收有动态注册静态注册两种方式,这篇博客沿着动态广播的注册、发送和接收三条路线开展探究。

动态广播的注册

首先,先整理一波动态注册的鸟瞰图
在这里插入图片描述

从图中可以看到
1)代码中调用的egisterReceiver(BroadcastReceiver, IntentFilter),在ContextImpl.java中实现(关于Context和Activity的关联,可以翻看我的前一篇博文),实际真正是ActivityManagerService去注册广播。
2)再通过跨进程通讯(这里采用的是binder),来获取用注册广播的服务,该服务的实现类在ActivityServiceManager.java。

开始从源码进行分析:

@Override
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
        return registerReceiver(receiver, filter, null, null);
    }
 @Override
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
            String broadcastPermission, Handler scheduler) {
        return registerReceiverInternal(receiver, getUserId(),
                filter, broadcastPermission, scheduler, getOuterContext(), 0);
    }

接下来看registerReceiverInternal方法:

 private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
            IntentFilter filter, String broadcastPermission,
            Handler scheduler, Context context, int flags) {
        //IIntentReceiver是用于后续跨进程分发广播时的binder对象
        IIntentReceiver rd = null;
        if (receiver != null) {
            if (mPackageInfo != null && context != null) {
                ...
                //获取IIntentReceiver对象
                //mPackageInfo是 当前进程的LoadedApk实例,LoadedApk用于记录 当前进程apk的本地信息。
                // **--->1**
                rd = mPackageInfo.getReceiverDispatcher(
                    receiver, context, scheduler,
                    mMainThread.getInstrumentation(), true);
           ...
        }
        try {
            //调用ams的registerReceiver(),并把IIntentReceiver类型的rd对象传入
             // **--->2**
            final Intent intent = ActivityManager.getService().registerReceiver(
                    mMainThread.getApplicationThread(), mBasePackageName, rd, filter,
                    broadcastPermission, userId, flags);
            ...
    }

看看 (注释1处) LoadedApk.java里的getReceiverDispatcher()

 public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
            Context context, Handler handler,
            Instrumentation instrumentation, boolean registered) {
        synchronized (mReceivers) {
            LoadedApk.ReceiverDispatcher rd = null;
            ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;
            if (registered) {
                //从mReceivers取出 该context 所对应的 map
                //了解下mReceivers的对象类型
                //private final ArrayMap<Context, ArrayMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers = new ArrayMap<>();
                //如果该 context ,首次注册广播,则 map 为空
                map = mReceivers.get(context);
                if (map != null) {
                    rd = map.get(r);
                }
            }
            if (rd == null) {
                //新建ReceiverDispatcher对象
                rd = new ReceiverDispatcher(r, context, handler,
                        instrumentation, registered);
                if (registered) {
                    if (map == null) {
                        map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
                        mReceivers.put(context, map);//存入map 于 mReceivers中
                    }
                    //map 存放广播接收者和对应的广播跨进程binder对象
                    map.put(r, rd);
                }
            } 
            ...
            //返回 rd 维护的 IIntentReceiver实例
            return rd.getIIntentReceiver();
        }
    }
<
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值