LocalBroadcastManager 相信有不少人会有点认生,他是android.support.v4中的一个类,本地广播,只在App内部传播,大家熟知的广播,BrocastReceiver是全局广播,可以跨进程通信,而LocalBroadcastManager,只是作为一个本地消息和数据传输的手段,当然,还是有不少人再用EventBus这类的消息事件库,不过我不喜欢用第三方的库,虽然EventBus也比较小,之前一直在使用BrocastReceiver,也比较随意,后来接触的项目多了,很多事情就需要考虑到了。
使用LocalBroadcastManager的好处:
1.只能传输在App内部,不会被其他App接收,确保数据安全
2.接收不到其他App广播,免干扰
3.比BrocastReceiver更加高效
不过要注意的是,LocalBroadcastManager不能静态注册,只能动态注册,这一特性也反应了第二点,不需要接收其他App的广播,那么我们来看下如何使用吧:
1private LocalBroadcastManager lm;
2private TestReceiver testReceiver;
3
4private void initReceiver() {
5 //获取实例
6 lm = LocalBroadcastManager.getInstance(this);
7 IntentFilter intentFilter = new IntentFilter("com.android.Test");
8 testReceiver = new TestReceiver();
9 //绑定
10 lm.registerReceiver(testReceiver,intentFilter);
11}
12
13private class TestReceiver extends BroadcastReceiver{
14
15 @Override
16 public void onReceive(Context context, Intent intent) {
17 String action = intent.getAction();
18 Toast.makeText(MainActivity.this, "action:" + action, Toast.LENGTH_SHORT).show();
19 }
20}
21
22@Override
23protected void onDestroy() {
24 super.onDestroy();
25 //解绑
26 lm.unregisterReceiver(testReceiver);
27}
使用的方式和BrocastReceiver也差不多,但是要注意的就是,我们用过LocalBroadcastManager.getInstance获取实例后,注册,解绑和发送都需要这个实例才可以
我们来看下LocalBroadcastManager的源码是如何工作的,其实他的源码也没有多少,他获取是通过单例来实现的
1@NonNull
2public static LocalBroadcastManager getInstance(@NonNull Context context) {
3 Object var1 = mLock;
4 synchronized(mLock) {
5 if (mInstance == null) {
6 mInstance = new LocalBroadcastManager(context.getApplicationContext());
7 }
8
9 return mInstance;
10 }
11}
12
13private LocalBroadcastManager(Context context) {
14 this.mAppContext = context;
15 this.mHandler = new Handler(context.getMainLooper()) {
16 public void handleMessage(Message msg) {
17 switch(msg.what) {
18 case 1:
19 LocalBroadcastManager.this.executePendingBroadcasts();
20 break;
21 default:
22 super.handleMessage(msg);
23 }
24
25 }
26 };
27}
单例后,在构造函数里初始化了一个Handler,这个Handler我们等下将,接着我们先来看下他的注册:
1public void registerReceiver(@NonNull BroadcastReceiver receiver, @NonNull IntentFilter filter) {
2 HashMap var3 = this.mReceivers;
3 synchronized(this.mReceivers) {
4 //构建广播消息体
5 LocalBroadcastManager.ReceiverRecord entry = new LocalBroadcastManager.ReceiverRecord(filter, receiver);
6 ArrayList filters = (ArrayList)this.mReceivers.get(receiver);
7 if (filters == null) {
8 filters = new ArrayList(1);
9 //添加接收者
10 this.mReceivers.put(receiver, filters);
11 }
12
13 filters.add(entry);
14
15 for(int i = 0; i < filter.countActions(); ++i) {
16 String action = filter.getAction(i);
17 ArrayList entries = (ArrayList)this.mActions.get(action);
18 if (entries == null) {
19 entries = new ArrayList(1);
20 //关联广播
21 this.mActions.put(action, entries);
22 }
23 entries.add(entry);
24 }
25 }
26}
注册的时候,他先构建了一个广播信息体ReceiverRecord,并且将我们注册传入的信息添加到Receiver,然后遍历Action,并且关联Action和事件,然后调用sendBroadcast去发送广播,他对数据做了处理之后,开始分类,也就有了我们的Bundler,Data之类的数据了,其实最后调用的代码:
1this.mPendingBroadcasts.add(new LocalBroadcastManager.BroadcastRecord(intent, receivers));
2if (!this.mHandler.hasMessages(1)) {
3 this.mHandler.sendEmptyMessage(1);
4}
就是这一段,这一段也很简单,将广播加入mPendingBroadcasts后发送一个What为1的Handler,而这个Handler就是之前获取单例后他在构造方法里创建的,所以你看这个what=1的判断里,他最终执行的函数为executePendingBroadcasts,代码不多,可以贴出来:
1void executePendingBroadcasts() {
2 while(true) {
3 HashMap var2 = this.mReceivers;
4 LocalBroadcastManager.BroadcastRecord[] brs;
5 synchronized(this.mReceivers) {
6 int N = this.mPendingBroadcasts.size();
7 if (N <= 0) {
8 return;
9 }
10
11 brs = new LocalBroadcastManager.BroadcastRecord[N];
12 this.mPendingBroadcasts.toArray(brs);
13 this.mPendingBroadcasts.clear();
14 }
15 for(int i = 0; i < brs.length; ++i) {
16 LocalBroadcastManager.BroadcastRecord br = brs[i];
17 int nbr = br.receivers.size();
18
19 for(int j = 0; j < nbr; ++j) {
20 LocalBroadcastManager.ReceiverRecord rec = (LocalBroadcastManager.ReceiverRecord)br.receivers.get(j);
21 if (!rec.dead) {
22 rec.receiver.onReceive(this.mAppContext, br.intent);
23 }
24 }
25 }
26 }
27}
我们可以通过这个双层for循环看到他最终是取得了监听的广播消息体brs里的数据,得到一个BroadcastRecord,然后调用br.receivers.get获取到接收对象rec,再通过rec.receiver.onReceive通知监听着,实现了消息的发送和接收
整个设计理念就是观察者模式了,对象一对多的关系依赖,当一个对象发生改变的时候,他的所有依赖者都将受到通知并且自动更新。
开车完毕,Over!!!
征稿:科技互联网,技术类文章
投稿方式:
发送文章链接地址到邮箱:[email protected]
注明“投稿”,收到会回复哟