迷茫时该如何选择?
1.本地广播和全局广播
1.1本地广播:
广播事件的发送和接收都在本应用,不影响其他应用也不受其他应用影响,只能被动态注册,不能静态注册,主要用法都在LocalBroadcastManager类中。
1.2全局广播:
可以接收其他应用发的广播,也可以发送广播让其他应用接收,全局广播既可以动态注册,也可以静态注册,接受其他应用和系统广播是全局广播的一个重要应用点。总体来说两者应用场景不同。
全局广播发送和接收限制设置:
(1)不让别的应用收到自己发送的广播
在Androidmanifest.xml中为BroadcastReceiver添加权限,如果是自定义权限记得先声明:
<permission android:name = "com.android.permission.quanxian"/>
发送广播是传入:
public void sendOrderedBroadcast(Intent intent, String receiverPermission)
sendBroadcast(intent, "com.android.permission.quanxian ");
只有具有permission权限的Receiver才能接收此广播要接收该广播,在Receiver应用的AndroidManifest.xml中要添加对应的相应的权限。
(2)过滤掉自己不愿接收的广播。
android:exported 此broadcastReceiver能否接收其他App的发出的广播,这个属性默认值有点意思,其默认值是由receiver中有无intent-filter决定的,如果有intent-filter,默认值为true,否则为false。
android:permission设置之后,只有具有相应权限的广播发送方发送的广播才能被此broadcastReceiver所接收;
上述设置也可以达到接收或者不接收的目的,但是全局广播其实原理是利用binder机制和AMS进行交互如果只是应用内使用,资源耗费或者说延时还是可以优化的。
2 本地广播使用
public class Demo3 extends AppCompatActivity {
private MyBroadcastReceiver mBroadcastReceiver;
private TextView mTv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTv = findViewById(R.id.clicke);
initEvent();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.ldx.demo");
LocalBroadcastManager.getInstance(this).registerReceiver(mBroadcastReceiver, intentFilter);
}
private void initEvent() {
mTv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction("com.ldx.demo");
LocalBroadcastManager.getInstance(Demo3.this).sendBroadcast(intent);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mBroadcastReceiver);
}
class MyBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
}
}
}
3 本地广播的实现原理
单例LocalBroadcastManager
全部逻辑都在LocalBroadcastManager中,LocalBroadcastManager提供了单例获取的getInstance:
@NonNull
public static LocalBroadcastManager getInstance(@NonNull Context context) {
synchronized (mLock) {
if (mInstance == null) {
mInstance = new LocalBroadcastManager(context.getApplicationContext());
}
return mInstance;
}
}
同时初始化了一个Handler:
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);
}
}
};
}
所以猜测是利用Handler向Receiver发送信息。
两个静态final内部类:
static final class ReceiverRecord
static final class BroadcastRecord
ReceiverRecord
ReceiverRecord:用来标识注册的单个广播,包括intentFilter和receiver,每次注册就会生成一个ReceiverRecord。
private static final class ReceiverRecord {
//记录intentFilter,意图过滤
final IntentFilter filter;
//记录广播接收者
final BroadcastReceiver receiver;
boolean broadcasting;
boolean dead;
ReceiverRecord(IntentFilter _filter, BroadcastReceiver _receiver) {
filter = _filter;
receiver = _receiver;
}
}
BroadcastRecord
BroadcastRecord记录一个意图对应的多个接收者,发送回复信息给Receiver时可以通过这个结构查找接收者。
private static final class BroadcastRecord {
//记录当前意图
final Intent intent;
//符合意图的ReceiverRecord
final ArrayList<ReceiverRecord> receivers;
BroadcastRecord(Intent _intent, ArrayList<ReceiverRecord> _receivers) {
intent = _intent;
receivers = _receivers;
}
}
LocalBroadcastManager中变量
//当前所有注册广播
private final HashMap<BroadcastReceiver, ArrayList<ReceiverRecord>> mReceivers
= new HashMap<>();
//有特定意图的广播
private final HashMap<String, ArrayList<ReceiverRecord>> mActions = new HashMap<>();
//待发送的广播
private final ArrayList<BroadcastRecord> mPendingBroadcasts = new ArrayList<>();
static final int MSG_EXEC_PENDING_BROADCASTS = 1;
private final Handler mHandler;
注册广播:
public void registerReceiver(@NonNull BroadcastReceiver receiver,
@NonNull IntentFilter filter) {
synchronized (mReceivers) {
// 新的注册,生成ReceiverRecord
ReceiverRecord entry = new ReceiverRecord(filter, receiver);
ArrayList<ReceiverRecord> filters = mReceivers.get(receiver);
// 最终添加到mReceivers中,一个广播接受者可能有多个意图过滤,场景类似对同一个BroadcastReceiver多次调用registerReceiver,每次意图过滤都不相同。
if (filters == null) {
filters = new ArrayList<>(1);
mReceivers.put(receiver, filters);
}
filters.add(entry);
//遍历意图过滤,获取action,每个action 对应多个ReceiverRecord,也就是一个Action对应多个接收者
for (int i=0; i<filter.countActions(); i++) {
String action = filter.getAction(i);
ArrayList<ReceiverRecord> entries = mActions.get(action);
if (entries == null) {
entries = new ArrayList<ReceiverRecord>(1);
mActions.put(action, entries);
}
entries.add(entry);
}
}
}
解除注册广播:
public void unregisterReceiver(@NonNull BroadcastReceiver receiver) {
synchronized (mReceivers) {
//从mReceivers中删除注册的广播,返回它的意图过滤列表
final ArrayList<ReceiverRecord> filters = mReceivers.remove(receiver);
if (filters == null) {
return;
}
//遍历意图过滤列表
for (int i=filters.size()-1; i>=0; i--) {
//通过意图找到对应的ReceiverRecord
final ReceiverRecord filter = filters.get(i);
filter.dead = true;
//找到所有对应的Action
for (int j=0; j<filter.filter.countActions(); j++) {
final String action = filter.filter.getAction(j);
//从mActions中获取ReceiverRecord,因为一个Action对应多个ReceiverRecord,解注册之后需要删除对应的RR
final ArrayList<ReceiverRecord> receivers = mActions.get(action);
if (receivers != null) {
for (int k=receivers.size()-1; k>=0; k--) {
final ReceiverRecord rec = receivers.get(k);
if (rec.receiver == receiver) {
rec.dead = true;
receivers.remove(k);
}
}
//删除之后如果当前Action对应的RR没有了,就直接删除,应为不需要此Action对应RR了
if (receivers.size() <= 0) {
mActions.remove(action);
}
}
}
}
}
}
发送广播:
public boolean sendBroadcast(@NonNull Intent intent) {
synchronized (mReceivers) {
//首先获取Action及其他参数
final String action = intent.getAction();
final String type = intent.resolveTypeIfNeeded(
mAppContext.getContentResolver());
final Uri data = intent.getData();
final String scheme = intent.getScheme();
final Set<String> categories = intent.getCategories();
final boolean debug = DEBUG ||
((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
//获取Action对应的ReceiverRecord
ArrayList<ReceiverRecord> entries = mActions.get(intent.getAction());
if (entries != null) {
if (debug) Log.v(TAG, "Action list: " + entries);
ArrayList<ReceiverRecord> receivers = null;
for (int i=0; i<entries.size(); i++) {
ReceiverRecord receiver = entries.get(i);
if (debug) Log.v(TAG, "Matching against filter " + receiver.filter);
if (receiver.broadcasting) {
continue;
}
int match = receiver.filter.match(action, type, scheme, data,
categories, "LocalBroadcastManager");
if (match >= 0) {
if (debug) Log.v(TAG, " Filter matched! match=0x" +
Integer.toHexString(match));
if (receivers == null) {
receivers = new ArrayList<ReceiverRecord>();
}
//符合条件,修改状态为true,receivers为需要接受的列表
receivers.add(receiver);
receiver.broadcasting = true;
} else {
if (debug) {
String reason;
switch (match) {
case IntentFilter.NO_MATCH_ACTION: reason = "action"; break;
case IntentFilter.NO_MATCH_CATEGORY: reason = "category"; break;
case IntentFilter.NO_MATCH_DATA: reason = "data"; break;
case IntentFilter.NO_MATCH_TYPE: reason = "type"; break;
default: reason = "unknown reason"; break;
}
Log.v(TAG, " Filter did not match: " + reason);
}
}
}
if (receivers != null) {
//修改状态
for (int i=0; i<receivers.size(); i++) {
receivers.get(i).broadcasting = false;
}
//加入到发送列表中,等待发送
mPendingBroadcasts.add(new BroadcastRecord(intent, receivers));
if (!mHandler.hasMessages(MSG_EXEC_PENDING_BROADCASTS)) {
mHandler.sendEmptyMessage(MSG_EXEC_PENDING_BROADCASTS);
}
return true;
}
}
}
return false;
}