android 本地广播原理,本地广播原理

简介

本地广播:发送的广播事件不被其他应用程序获取,也不能响应其他应用程序发送的广播事件。本地广播只能被动态注册,不能静态注册。动态注册或方法时需要用到LocalBroadcastManager。

本地广播使用的是观察者模式

本地广播的基本使用

注册广播

localBroadcast = new LocalBroadcast();

IntentFilter intentFilter = new IntentFilter();

intentFilter.addAction("com.wuyazhou.test");

LocalBroadcastManager.getInstance(this).registerReceiver(localBroadcast, intentFilter);

解注册广播

LocalBroadcastManager.getInstance(this).unregisterReceiver(localBroadcast);

发送广播

LocalBroadcastManager.getInstance(BroadcastActivity.this).sendBroadcast(new Intent("com.wuyazhou.test"));

本地广播的实现原理

通过本地广播的基本使用知道本地广播和全局广播在形式上主要的不同源于LocalBroadcastManager这个类。

1. 实例化本地广播管理者LocalBroadcastManager.getInstance(this)

/*单例模式,进程中维持一份数据*/

private static LocalBroadcastManager mInstance;

public static LocalBroadcastManager getInstance(Context context) {

synchronized (mLock) {

if (mInstance == null) {

mInstance = new LocalBroadcastManager(context.getApplicationContext());

}

return mInstance;

}

}

private LocalBroadcastManager(Context context) {

//初始化环境

mAppContext = context;

//通过主线程的Looper构造的Handler

mHandler = new Handler(context.getMainLooper()) {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case MSG_EXEC_PENDING_BROADCASTS:

executePendingBroadcasts();

break;

default:

super.handleMessage(msg);

}

}

};

}

2. LocalBroadcastManager类的两个内部数据类(ReceiverRecord 和 BroadcastRecord )和三个数据集合。

private static final class ReceiverRecord {

//记录当前意图过滤

final IntentFilter filter;

//记录当前广播接收器

final BroadcastReceiver receiver;

//是否正在广播

boolean broadcasting;

//是否挂掉

boolean dead;

ReceiverRecord(IntentFilter _filter, BroadcastReceiver _receiver) {

filter = _filter;

receiver = _receiver;

}

}

private static final class BroadcastRecord {

//记录当前意图

final Intent intent;

//记录符合当前意图的ReceivedRecord数据结构

final ArrayList receivers;

BroadcastRecord(Intent _intent, ArrayList _receivers) {

intent = _intent;

receivers = _receivers;

}

}

//记录当前注册所有广播

private final HashMap> mReceivers= new HashMap<>();

//记录当前拥有某Action的广播

private final HashMap> mActions = new HashMap<>();

//记录当前等待执行的广播

private final ArrayList mPendingBroadcasts = new ArrayList<>();

3. 注册广播LocalBroadcastManager.getInstance(this)

.registerReceiver(localBroadcast, intentFilter);

public void registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {

synchronized (mReceivers) {

/*将广播接收者和对应的意图过滤匹配起来,注意:一个广播接受者可能有多个意图过滤。*/

ReceiverRecord entry = new ReceiverRecord(filter, receiver);

ArrayList filters = mReceivers.get(receiver);

if (filters == null) {

filters = new ArrayList<>(1);

mReceivers.put(receiver, filters);

}

filters.add(entry);

//将意图过滤中的Action和对应得广播接受者对应起来,注意:一个Action可能对应多个广播接受者

for (int i=0; i

String action = filter.getAction(i);

ArrayList entries = mActions.get(action);

if (entries == null) {

entries = new ArrayList(1);

mActions.put(action, entries);

}

entries.add(entry);

}

}

}

4. 解注册广播LocalBroadcastManager.getInstance(this)

.unregisterReceiver(localBroadcast);

public void unregisterReceiver(BroadcastReceiver receiver) {

synchronized (mReceivers) {

//删除指定广播,并返回指定广播对应的所有意图过滤。

final ArrayList filters = mReceivers.remove(receiver);

if (filters == null) {

return;

}

/*遍历指定广播的所有意图过滤*/

for (int i=filters.size()-1; i>=0; i--) {

final ReceiverRecord filter = filters.get(i);

//标记当前广播挂掉

filter.dead = true;

/*遍历过滤意图的所有Action*/

for (int j=0; j

final String action = filter.filter.getAction(j);

/*根据Action遍历mAction列表*/

final ArrayList receivers = mActions.get(action);

if (receivers != null) {

for (int k=receivers.size()-1; k>=0; k--) {

final ReceiverRecord rec = receivers.get(k);

/*mAction列表中如果有指定广播要删除,并标记mAction列表中的该广播挂掉*/

if (rec.receiver == receiver) {

rec.dead = true;

receivers.remove(k);

}

}

if (receivers.size() <= 0) {

mActions.remove(action);

}

}

}

}

}

}

5. 发送广播LocalBroadcastManager.getInstance(BroadcastActivity.this)

.sendBroadcast(new Intent(“com.wuyazhou.test”));

public boolean sendBroadcast(Intent intent) {

synchronized (mReceivers) {

/*获取意图中的过滤信息*/

final String action = intent.getAction(); //行为 Action

final String type = intent.resolveTypeIfNeeded( //类型 Type

mAppContext.getContentResolver());

final Uri data = intent.getData(); //URI

final String scheme = intent.getScheme(); //scheme

final Set categories = intent.getCategories(); // 种类

//根据意图中的Action获取mAction列表中所有的广播接收者

ArrayList entries = mActions.get(intent.getAction());

if (entries != null) {

//保存符合意图的广播接收者

ArrayList receivers = null;

/*遍历广播接受者*/

for (int i=0; i

ReceiverRecord receiver = entries.get(i);

/*判断该广播是否正在广播,如果是则放弃本次广播*/

if (receiver.broadcasting) {

continue;

}

/*判断该广播接受者是否符合意图*/

int match = receiver.filter.match(action, type, scheme, data,

categories, "LocalBroadcastManager");

if (match >= 0) {

if (receivers == null) {

receivers = new ArrayList();

}

/*如果该广播接收者符合意图,则保存并标记正在广播*/

receivers.add(receiver);

receiver.broadcasting = true;

} else {

}

}

/*遍历符合意图的广播接收者,将标记为设置为广播结束*/

if (receivers != null) {

for (int i=0; i

receivers.get(i).broadcasting = false;

}

/*将符合意图的广播接受者和意图通过BroadcastRecord类对应起来,然后通过Handle发送*/

mPendingBroadcasts.add(new BroadcastRecord(intent, receivers));

if (!mHandler.hasMessages(MSG_EXEC_PENDING_BROADCASTS)) {

mHandler.sendEmptyMessage(MSG_EXEC_PENDING_BROADCASTS);

}

return true;

}

}

}

return false;

}

6. 最后通过在构造方法中构建的主线程Handler发送消息 执行executePendingBroadcasts()该方法

/*执行等待的广播发送*/

private void executePendingBroadcasts() {

for (int j=0; j

final ReceiverRecord rec = br.receivers.get(j);

if (!rec.dead) {

rec.receiver.onReceive(mAppContext, br.intent);

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值