博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BroadcastReceiver和LocalBroadcastManager
阅读量:4097 次
发布时间:2019-05-25

本文共 10214 字,大约阅读时间需要 34 分钟。

BroadcastReceiver

1、发送和接收广播
// 全局广播        // 发送        val intent = Intent()        intent.action=ActionConstant.ACTION_ONE        intent.putExtra("EXTRA", "全局广播")        sendBroadcast(intent)            // 接收广播        private fun register() {        val intentFilter = IntentFilter()        intentFilter.addAction(ActionConstant.ACTION_ONE)        registerReceiver(InnerBroadcastReceiver(), intentFilter)    }        // 本地广播            // 发送        val intent = Intent()        intent.action=ActionConstant.ACTION_TWO        intent.putExtra("EXTRA", "本地广播")        val manager=LocalBroadcastManager.getInstance(this)        manager.sendBroadcast(intent)                // 接收        val localBroadcastManager = LocalBroadcastManager.getInstance(this)        val intentFilter = IntentFilter()        intentFilter.addAction(ActionConstant.ACTION_TWO)        localBroadcastManager.registerReceiver(InnerBroadcastReceiver(), intentFilter)             inner class InnerBroadcastReceiver : BroadcastReceiver() {        override fun onReceive(context: Context?, intent: Intent?) {            when (intent?.action) {                ActionConstant.ACTION_ONE -> {                    val str = intent?.getStringExtra("EXTRA")                    Log.e("peter", "接收到全局广播-> $str")                    mText?.text = str                }            }        }    }
2、知识点梳理

(1)broadcastReceiver的响应时间为10s,超过10s无响应,将不会再次收到该广播

(2)onReceiver方法中不允许显示popUpWindow

LocalBroadcastManager

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;        // 获取主线程的looper对象创建handler        this.mHandler = new Handler(context.getMainLooper()) {            public void handleMessage(Message msg) {                switch(msg.what) {                // 根据what值处理消息                case 1:                    LocalBroadcastManager.this.executePendingBroadcasts();                    break;                default:                    super.handleMessage(msg);                }            }        };    }
// 注册广播
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
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); // 遍历action ArrayList
entries = (ArrayList)this.mActions.get(action); if (entries == null) { entries = new ArrayList(1); // 存储action this.mActions.put(action, entries); } // 添加到arrayList中 entries.add(entry); } } }
发送广播
public boolean sendBroadcast(@NonNull Intent intent) {        HashMap var2 = this.mReceivers;        synchronized(this.mReceivers) {            String action = intent.getAction();            String type = intent.resolveTypeIfNeeded(this.mAppContext.getContentResolver());            Uri data = intent.getData();            String scheme = intent.getScheme();            Set
categories = intent.getCategories(); boolean debug = (intent.getFlags() & 8) != 0; if (debug) { Log.v("LocalBroadcastManager", "Resolving type " + type + " scheme " + scheme + " of intent " + intent); } ArrayList
entries = (ArrayList)this.mActions.get(intent.getAction()); if (entries != null) { if (debug) { Log.v("LocalBroadcastManager", "Action list: " + entries); } ArrayList
receivers = null; int i; for(i = 0; i < entries.size(); ++i) { LocalBroadcastManager.ReceiverRecord receiver = (LocalBroadcastManager.ReceiverRecord)entries.get(i); if (debug) { Log.v("LocalBroadcastManager", "Matching against filter " + receiver.filter); } if (receiver.broadcasting) { if (debug) { Log.v("LocalBroadcastManager", " Filter's target already added"); } } else { // 过滤合适的receiver int match = receiver.filter.match(action, type, scheme, data, categories, "LocalBroadcastManager"); if (match >= 0) { if (debug) { Log.v("LocalBroadcastManager", " Filter matched! match=0x" + Integer.toHexString(match)); } if (receivers == null) { receivers = new ArrayList(); } // 将符合条件的receiver添加到arraylist中 receivers.add(receiver); receiver.broadcasting = true; } else if (debug) { String reason; switch(match) { case -4: reason = "category"; break; case -3: reason = "action"; break; case -2: reason = "data"; break; case -1: reason = "type"; break; default: reason = "unknown reason"; } Log.v("LocalBroadcastManager", " Filter did not match: " + reason); } } } if (receivers != null) { for(i = 0; i < receivers.size(); ++i) { ((LocalBroadcastManager.ReceiverRecord)receivers.get(i)).broadcasting = false; } // 将本地广播添加到mPendingBroadcasts集合中 this.mPendingBroadcasts.add(new LocalBroadcastManager.BroadcastRecord(intent, receivers)); if (!this.mHandler.hasMessages(1)) { // 通过handler发送消息 this.mHandler.sendEmptyMessage(1); } return true; } } return false; } }
反注册广播
public void unregisterReceiver(@NonNull BroadcastReceiver receiver) {        HashMap var2 = this.mReceivers;        synchronized(this.mReceivers) {            ArrayList
filters = (ArrayList)this.mReceivers.remove(receiver); // 遍历filter if (filters != null) { for(int i = filters.size() - 1; i >= 0; --i) { LocalBroadcastManager.ReceiverRecord filter = (LocalBroadcastManager.ReceiverRecord)filters.get(i); filter.dead = true; // 遍历filter中action for(int j = 0; j < filter.filter.countActions(); ++j) { String action = filter.filter.getAction(j); ArrayList
receivers = (ArrayList)this.mActions.get(action); if (receivers != null) { for(int k = receivers.size() - 1; k >= 0; --k) { LocalBroadcastManager.ReceiverRecord rec = (LocalBroadcastManager.ReceiverRecord)receivers.get(k); // 移除filter实现 if (rec.receiver == receiver) { rec.dead = true; receivers.remove(k); } } if (receivers.size() <= 0) { // 移除action this.mActions.remove(action); } } } } } } }
接收广播

重点查看executePendingBroadcasts方法

void executePendingBroadcasts() {    // while true进行循环receivers        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();            }            // 找到每个receiver            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);                    // receiver存活状态调用receiver的onReceive方法                    if (!rec.dead) {                        rec.receiver.onReceive(this.mAppContext, br.intent);                    }                }            }        }    }

通过遍历存储的receiver,调用receiver的onReceive方法实现广播的接收

小结:

BroadcastManager使用Binder机制实现,可以用作实现进程间通信,但是可以被其他app监听到,安全性差。

LocalBroadcastManager使用Handler实现,通过handler发送和接收消息的方式,实现应用内广播通信,安全性高。

转载地址:http://pioii.baihongyu.com/

你可能感兴趣的文章
电机堵转
查看>>
carzepony也在想往FreeRTOS上迁移
查看>>
ROS是不是可以理解成一个虚拟机,就是操作系统之上的操作系统
查看>>
用STL algorithm轻松解决几道算法面试题
查看>>
ACfly之所以不怕炸机因为它觉得某个传感器数据不安全就立马不用了
查看>>
我发觉,不管是弄ROS OPENCV T265二次开发 SDK开发 caffe PX4 都是用的C++
查看>>
ROS的安装(包含文字和视频教程,我的ROS安装教程以这篇为准)
查看>>
原来我之前一直用的APM固件....现在很多东西明白了。
查看>>
realsense-ros里里程计相关代码
查看>>
似乎写个ROS功能包并不难,你会订阅话题发布话题,加点逻辑处理,就可以写一些基础的ROS功能包了。
查看>>
找到了中文版的mavlink手册
查看>>
浅谈飞控开发的仿真功能
查看>>
我觉得在室内弄无人机开发装个防撞机架还是很有必要的,TBUS就做得很好。
查看>>
serial也是见到很多次了,似乎它就是一种串行通信协议
查看>>
TBUS的一些信息
查看>>
专业和业余的区别就在于你在基础在基本功打磨练习花的时间
查看>>
通过mavlink实现自主航线的过程笔记
查看>>
Ardupilot飞控Mavlink代码学习
查看>>
这些网站有一些嵌入式面试题合集
查看>>
我觉得刷题是有必要的,不然小心实际被问的时候懵逼,我觉得你需要刷个50份面试题。跟考研数学疯狂刷卷子一样!
查看>>