LocalBroadcastManager从使用到源码分析

前言

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

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页