前言
自从工作后好长时间都没写博客了,一来是实在太忙,二来也沉不下心来看技术文章心态比之前在学校的时候浮躁很多。最近项目里面用到了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中。
未完待续…