前言:

Android 本地广播实现非常简单,就一个类。android.support.v4.content.LocalBroadcastManager 大概200行代码。我们看下关键的几个地方

注册广播

    public void registerReceiver(@NonNull BroadcastReceiver receiver, @NonNull IntentFilter filter) {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);}}}

注册广播主要是把receiver 使用List保存起来。

发送广播

    public boolean sendBroadcast(@NonNull Intent intent) {synchronized(this.mReceivers) {String action = intent.getAction();String type = intent.resolveTypeIfNeeded(this.mAppContext.getContentResolver());Uri data = intent.getData();String scheme = intent.getScheme();Set<String> categories = intent.getCategories();boolean debug = (intent.getFlags() & 8) != 0;if (debug) {Log.v("LocalBroadcastManager", "Resolving type " + type + " scheme " + scheme + " of intent " + intent);}ArrayList<LocalBroadcastManager.ReceiverRecord> entries = (ArrayList)this.mActions.get(intent.getAction());if (entries != null) {if (debug) {Log.v("LocalBroadcastManager", "Action list: " + entries);}ArrayList<LocalBroadcastManager.ReceiverRecord> 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 {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();}receivers.add(receiver);receiver.broadcasting = true;} }}if (receivers != null) {for(i = 0; i < receivers.size(); ++i) {((LocalBroadcastManager.ReceiverRecord)receivers.get(i)).broadcasting = false;}this.mPendingBroadcasts.add(new LocalBroadcastManager.BroadcastRecord(intent, receivers));if (!this.mHandler.hasMessages(1)) {this.mHandler.sendEmptyMessage(1);}return true;}}return false;}}

发送广播的时候,会根据action 匹配list 里面的所有receiver,找到匹配的receiver 放到mPendingBroadcasts 变量里面,然后通过handler发送消息,在hander 线程里面调用onReceive方法。

mHandler初始化

    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);}}};}

我们看到mHandler其实就是main thread.

回调所有的广播注册者

    void executePendingBroadcasts() {while(true) {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);}}}}}

因为本地广播实现是使用list 保存所有的receive, 然后在主线程遍历所有的receive,所以本地广播是不能跨进程使用的。

Android LocalBroadcast 本地广播源码解析相关推荐

  1. android handler2--消息队列源码解析

    android handler2–消息队列源码解析 1.Looper 对于Looper主要是prepare()和loop()两个方法. 首先看prepare()方法 public static fin ...

  2. Android Hawk数据库的源码解析,Github开源项目,基于SharedPreferences的的存储框架

    今天看了朋友一个项目用到了Hawk,然后写了这边文章 一.了解一下概念 Android Hawk数据库github开源项目 Hawk是一个非常便捷的数据库.操作数据库只需一行代码,能存任何数据类型. ...

  3. android网络框架retrofit源码解析二

    注:源码解析文章参考了该博客:http://www.2cto.com/kf/201405/305248.html 前一篇文章讲解了retrofit的annotation,既然定义了,那么就应该有解析的 ...

  4. Android手游 “2048” 源码解析

    转载请写明出处:http://blog.csdn.net/big_heart_c 下面所解析的源码是来自极客学院"Android 2048 "中的源码,读者可以从 https:// ...

  5. Android 常用开源框架源码解析 系列 (四)Glide

    一.定义  Glide 一个被google所推荐的图片加载库,作者是bumptech.对Android SDk 最低要求是 API 10  与之功能类似的是Square公司的picasso  二.基本 ...

  6. Android存储之SharedPreferences源码解析

    个人博客:haichenyi.com.感谢关注 1. 目录 1–目录 2–简介 3–getSharedPreferences会不会阻塞线程,为什么? 4–get操作,为什么有时候会卡顿? 5–comm ...

  7. Android之EventBus框架源码解析下(源码解析)

    转载请标明出处:[顾林海的博客] 个人开发的微信小程序,目前功能是书籍推荐,后续会完善一些新功能,希望大家多多支持! 前言 EventBus是典型的发布订阅模式,多个订阅者可以订阅某个事件,发布者通过 ...

  8. Android 常用开源框架源码解析 系列 (九)dagger2 呆哥兔 依赖注入库

    一.前言 依赖注入定义 目标类中所依赖的其他的类的初始化过程,不是通过手动编码的方式创建的. 是将其他的类已经初始化好的实例自动注入的目标类中. "依赖注入"也是面向对象编程的 设 ...

  9. Android EdgeEffect 使用 和 源码解析

    创建EdgeEffect private EdgeEffect leftEdgeEffect;private void init(Context context) {leftEdgeEffect = ...

最新文章

  1. Matlab练习:timer(2)
  2. 无招胜有招之Java进阶JVM(六)JVM 参数及调优
  3. APPENDIX B-菜单计划和食谱-Pagano博士的七天菜单计划样例-未完待续
  4. 用Microwindows(Nano-X)编写中文程序
  5. linux对当前使用的分区分割,实例解说Linux中fdisk分区使用方法
  6. iApp对接hybbs社区APP源码
  7. MetadataCache分析
  8. [转帖]解密微软中间语言MSIL之调试程序(1)
  9. JBDC操作事务源码解析
  10. 关于高德地图坐标批量手动拾取的简易办法
  11. 在光标位置处插入图片
  12. 高中计算机网络说课,高一信息技术说课稿
  13. PS利用色彩范围抠图
  14. coap 返回版本信息_CoAP协议学习笔记
  15. Windows10玩转Linux子系统(WSL)
  16. 【数据分析】2022 年将占据主导地位的 3 种数据和分析趋势
  17. Ubuntu搭建FTP服务器后用filezella连接报错
  18. matplotlib生成没有留白的图片
  19. numpy的学习,全是源码,勿喷
  20. 基恩士编程c语言,基恩士xg7000系列.pdf

热门文章

  1. center6linux ip设置,centos6固定ip地址
  2. 943602cs 蓝牙驱动 win10_英特尔升级WiFi 和蓝牙驱动,Win10 更新5月版稳了
  3. 用java编写运行的小游戏_第一次用Java编写小游戏!
  4. CUDA学习-函数前缀__global__
  5. c 清除 html标签,13.4. 去除HTML的标签tag:htmlRemoveTag
  6. php调用txt接口,PHP 如何更优雅地调用 API 接口
  7. 软件版本号命名规范_电影录音部门和剪辑部门交互规范的参考
  8. 【入门须知】学DIV CSS技术如何入门?
  9. 浅说Java中的反射机制(一)
  10. 学习javascript 的一点感想