Android之LocalBroadcastManager源码解析

LocalBroadcastManager

在项目中遇到LocalBroadcastManager,看英文大概知道是“管理本地广播”的,翻了一下api文档,发现他就是用来注册,发送本地广播的,用于应用内通信。

Helper to register for and send broadcasts of Intents to local objects within your process. This is has a number of advantages over sending global broadcasts with sendBroadcast(Intent):
用来注册发送本地应用Intent的广播,通过sendBroadcast发送全局的广播有以下优点:

    You know that the data you are broadcasting won't leave your app, so don't need to worry about leaking private data.
    It is not possible for other applications to send these broadcasts to your app, so you don't need to worry about having security holes they can exploit.
    It is more efficient than sending a global broadcast through the system. 
    广播的数据不会留在应用内,不用担心泄露私有的数据。
    其他应用程序不能发送这些广播到app内,不用担心一些安全漏洞被他们捕捉到。
    通过系统发送一个全局的广播会更加有效率。
注意:LocalBroadcastManager发送的广播不能被应用内跨进程接收

总结一下就是,LocalBroadcastManager是用来发送本地广播的,在应用内进行通信,比较安全,高效。

LocalBroadcastManager

下面我们来看一下LocalBroadcastManager的源码实现:

几个方法

getInstance(),获取LocalBroadcastManager实例
 // 单例模式
 public static LocalBroadcastManager getInstance(Context context) {
        synchronized (mLock) {
            if (mInstance == null) {
                mInstance = new LocalBroadcastManager(context.getApplicationContext());
            }
            return mInstance;
        }
    }

    // 在构造方法里面使用Handler机制
    private LocalBroadcastManager(Context context) {
        mAppContext = context;
        mHandler = new Handler(context.getMainLooper()) {

            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case MSG_EXEC_PENDING_BROADCASTS:
                    // 执行广播
                        executePendingBroadcasts();
                        break;
                    default:
                        super.handleMessage(msg);
                }
            }
        };
    }
registerReceiver(),注册广播

mReceivers是一个HashMap键是Receivers值是ArrayList filter,首先将
传进来的filter add到Receivers对应的ArrayList ,然后ReceiverRecord add到action对应的 ArrayList ,这样就完成注册

public void registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
        synchronized (mReceivers) {
            ReceiverRecord entry = new ReceiverRecord(filter, receiver);
            ArrayList<IntentFilter> filters = mReceivers.get(receiver);
            if (filters == null) {
                filters = new ArrayList<IntentFilter>(1);
                mReceivers.put(receiver, filters);
            }
            filters.add(filter);
            for (int i=0; i<filter.countActions(); i++) {
                String action = filter.getAction(i);
                ArrayList<ReceiverRecord> entries = mActions.get(action);
                if (entries == null) {
                    entries = new ArrayList<ReceiverRecord>(1);
                    mActions.put(action, entries);
                }
                entries.add(entry);
            }
        }
    }

sendBroadcast(Intent intent),发送广播

这里首先取出intent的action,然后拿到之前保存action,RecordReceiver的集合

       synchronized (mReceivers) {
            final String action = intent.getAction();
            final String type = intent.resolveTypeIfNeeded(
                    mAppContext.getContentResolver());
            final Uri data = intent.getData();
            final String scheme = intent.getScheme();
            final Set<String> categories = intent.getCategories();

            ArrayList<ReceiverRecord> entries = mActions.get(intent.getAction());
            if (entries != null) {
                ArrayList<ReceiverRecord> receivers = null;
                for (int i=0; i<entries.size(); i++) {
                    ReceiverRecord receiver = entries.get(i);          

     // 通过match找对应的filter
    if (match >= 0) {
                        if (receivers == null) {
                            receivers = new ArrayList<ReceiverRecord>();
                        }
                        receivers.add(receiver);
                        receiver.broadcasting = true;
                    }
                }

通过int match = receiver.filter.match()方法去找对应的filter

   int match = receiver.filter.match(action, type, scheme, data,categories, "LocalBroadcastManager");

找到之后,将所有注册该filter的广播接收者放到mPendingBroadcasts集合,然后通过handler发送消息。

  mPendingBroadcasts.add(new BroadcastRecord(intent, receivers));
                    if (!mHandler.hasMessages(MSG_EXEC_PENDING_BROADCASTS)) {
                        mHandler.sendEmptyMessage(MSG_EXEC_PENDING_BROADCASTS);
                    }

handler收到消息,执行executePendingBroadcasts()

    public void handleMessage(Message msg) {
                switch (msg.what) {
                    case MSG_EXEC_PENDING_BROADCASTS:
                        executePendingBroadcasts();
                        break;
                    default:
                        super.handleMessage(msg);
                }
            }

接下来就遍历广播接收者,执行onReceive方法,这样就完成了一次广播的发送。

for (int i=0; i<brs.length; i++) {
                BroadcastRecord br = brs[i];
                for (int j=0; j<br.receivers.size(); j++) {
                    br.receivers.get(j).receiver.onReceive(mAppContext, br.intent);
                }
            }
unregister

了解了怎么注册,那么解除也就是将receiver移除集合的逻辑操作了。

总结

通过查看源码,我们发现LocalBroadcastManager的实现也并不是那么复杂,只有有点耐心,是可以搞清楚里面的实现原理的!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值