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