LocalBroadcastManager从使用到源码分析

xiaoxiao2025-10-23  11

前言

自从工作后好长时间都没写博客了,一来是实在太忙,二来也沉不下心来看技术文章心态比之前在学校的时候浮躁很多。最近项目里面用到了LocalBroadcastManager虽然用起来很简单但是源码实现起来确实很值得学习的。所以本文先介绍LocalBroadcastManager的使用,然后再进一步分析源码的实现和相关的设计模式使用。

1.什么是LocalBroadcastManager

LocalBroadcastManager是本地广播管理类,本地广播作用于应用的内部,广播数据不会泄露,本应用也不会接收到其他应用的广播,因此安全性较高本地广播是在应用内部执行,无需跨进程逻辑,与普通广播相比效率更高使用简单,无需静态注册。LocalBroadcastManager也称为局部通知管理器,这种通知的好处是安全性高,效率也高,适合局部通信,可以用来代替Handler更新UI。

2.LocalBroadcastManager使用实例

本地广播的使用主要分为两个步骤:1.发送端发送广播,2.接收端接受广播并进行相关处理。 1.发送广播

Intent broadCastIntent = new Intent();//新建intent broadCastIntent.setAction(ACTION_LIVE_DATA_UPDATED);//给intent设置相关的action LocalBroadcastManager.getInstance(context).sendBroadcast(broadCastIntent);//发送广播

发送广播分为三步:新建一个intent给intent加上action然后获取LocalBroadcastManager的实例进行发送。 2.接收并处理广播 接受广播分为三步,新建BroadcastReceiver接收类,注册本地广播,从本地广播中注销。

//新建一个BroadcastReceiver在onReceive中处理接收到广播后的逻辑 BroadcastReceiver mLocalBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { } } //注册接收广播,通过intent附加的action来筛选需要监听的广播。注册广播后每次监听到广播变换的时候就可以在BroadcastReceiver 的onReceive方法中进行处理。 IntentFilter filter = new IntentFilter(); filter.addAction(ACTION_LIVE_DATA_UPDATED); LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(mLocalBroadcastReceiver, filter); //注销,当程序销毁的时候一定要注销广播,不然会造成内存泄漏 LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(mLocalBroadcastReceiver);

3.LocalBroadcastManager的实现原理

由本地广播的使用过程就很容易知道LocalBroadcastManager使用的是观察者模式,下面从源码分析LocalBroadcastManager是怎样实现这种观察者模式的。要彻底理解LocalBroadcastManager的实现就要了解LocalBroadcastManager中的数据结构。 3.1LocalBroadcastManager中的主要数据结构 1.ReceiverRecord内部类 ReceiverRecord是静态内部类,ReceiverRecord是对IntentFilter和Broadcast类的一个组合封装。代码如下

private static final class ReceiverRecord { final IntentFilter filter; final BroadcastReceiver receiver; boolean broadcasting; boolean dead; ReceiverRecord(IntentFilter _filter, BroadcastReceiver _receiver) { filter = _filter; receiver = _receiver; } @Override public String toString() { StringBuilder builder = new StringBuilder(128); builder.append("Receiver{"); builder.append(receiver); builder.append(" filter="); builder.append(filter); if (dead) { builder.append(" DEAD"); } builder.append("}"); return builder.toString(); } }

ReceiverRecord 的结构如图所示:

2.BroadcastRecord内部类 BroadcastRecord也是一个静态内部类,主要包含一个intent和一个ReceiverRecord队列代码如下:

private static final class BroadcastRecord { final Intent intent; final ArrayList<LocalBroadcastManager.ReceiverRecord> receivers; BroadcastRecord(Intent _intent, ArrayList<LocalBroadcastManager.ReceiverRecord> _receivers) { this.intent = _intent; this.receivers = _receivers; } }

3.mReceivers mReceivers是一个hashMap里面的结构如下代码所示:

HashMap<BroadcastReceiver, ArrayList<LocalBroadcastManager.ReceiverRecord>> mReceivers = new HashMap();

mReceivers中的key是BroadcastReceiver,value是元素为ReceiverRecord的ArrayList。 4.mActions mActions也是一个hashMap形式的代码如下:

HashMap<String, ArrayList<LocalBroadcastManager.ReceiverRecord>> mActions = new HashMap();

mActions和mReceivers的不同点在于mActions中的key是String类型的而mReceivers中的key是BroadcastReceiver的。 5.mPendingBroadcasts mPendingBroadcasts是一个ArrayList形式代码如下:

ArrayList<LocalBroadcastManager.BroadcastRecord> mPendingBroadcasts = new ArrayList();

分析LoaclBroadcastManager的源码最重要的是弄懂mReceivers,mActions,mPendingBroadcasts三者的作用和关系。 mReceivers中用于保存用户注册的广播和相关的过滤条件,下面看看注册广播的源代码:

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

由上面的代码可知,每当注册一个监听广播的时候,由BroadcastReceiver和IntentFilter 组成一个新的Entry并且由BroadcastReceiver作为key到mReceivers中查找保存有ReceiverRecord的ArrayList,如果没有就新建一个ArrayList,然后把当前产生的Entry放到ArrayList中。 未完待续…

转载请注明原文地址: https://www.6miu.com/read-5038405.html

最新回复(0)