Create 动态广播的注册和收发原理.md

master
Omooo 5 years ago
parent b6fec7d9b9
commit dea21c9edb
  1. 161
      blogs/Android/Framework/Interview/其他应用组件相关/动态广播的注册和收发原理.md

@ -0,0 +1,161 @@
---
动态广播的注册和收发原理
---
1. 动态广播的注册原理
2. 广播的发送原理
3. 广播的接收原理
#### 广播的注册
```java
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
return registerReceiver(receiver, filter, null, null);
}
```
```java
Intent registerReceiverInternal(BroadcastReceiver receiver, ...) {
IIntentReceiver rd = null;
schedule = mMainThread.getHandler();
rd = mPackageInfo.getReceiverDispatcher(receiver, context, schedule, ...);
return ActivityManagerNative.getDefault().registerReceiver(rd, filter, ...);
}
IIntentReceiver getReceiverDispatcher(BroadcastReceiver r, ...) {
ReceiverDispatcher rd = null;
ArrayMap<BroadcastReceiver, ReceiverDispatcher> map = null;
map = mReceivers.get(context);
rd = new ReceiverDispatcher(r, context, handler, ...);
map.put(r, rd);
return rd.getIIntentReceiver();
}
ReceiverDispatcher(BroadcastReceiver receiver, Context context, ...) {
mIIntentReceiver = new InnerReceiver(this, !registered);
mReceiver = receiver;
}
final static class InnerReceiver extends IIntentReceiver.Stub {
final WeakReference<ReceiverDispatcher> mDispatcher;
InnerReceiver(ReceiverDispatcher rd, boolean strong) {
mDispatcher = new WeakReference<ReceiverDispatcher>(fd);
}
}
```
引用链:
AMS -> IIntentReceiver -> ReceiverDispatcher -> BroadcastReceiver
AMS 是如何处理注册广播的?
```java
// AMS#registerReceiver
public Intent registerReceiver(IApplicationThread caller, ...) {
// ReceiverList: List<BroadcastFilter>
ReceiverList rl = nRigisterReceiver.get(receiver.asBinder());
if(rl == null){
rl = new ReceiverList(receiver, ...);
rl.app.receiver.add(rl);
mRegisterReceivers.put(receiver.asBinder(), rl);
}
BroadcastFilter bf = new BroadcastReceiver(filter, rl, ...);
rl.add(bf);
mReceiverResolver.addFilter(bf);
}
```
#### 广播的发送
```java
@Override
public void sendBroadcast(Intent intent) {
ActivityManagerNative.getDrfault().broadcastIntent(mMainThread.getApplicationThread(), intent, ...);
}
int broadcastIntent(IApplicationThread caller, Intent intent, ...) {
broadcastIntentLocked(callerApp, ...);
}
int broadcastIntentLocked(ProcessRecord callerApp, ...) {
registerReceivers = mReceiverResolver.queryIntent(intent, ...);
int NR = registedReceivers.size();
if(!ordered && NR > 0){
final BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, registeredReceivers, ...);
queue.enqueueParallelBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
registeredReceivers = null;
NR = 0;
}
}
// 处理广播分发的函数
final void processNextBroadcast(boolean fromMsg) {
BroadcastRecord r;
while(mParallelBroadcasts.size()>0){
r = mParallelBroadcasts.remove(0);
final int N = r.receivers.size();
for(int i=0;i<N;i++){
BroadcastFilter target = r.receivers.get(i);
deliverToRegisterReceiverLocked(r, target, false);
}
}
}
```
#### 广播的接收
```java
void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver, ...) {
if(app != null){
app.thread.scheduleRegisterReceiver(receiver, intent, ...);
} else {
receiver.performReceiver(intent, resultCode, data, ...);
}
}
void scheduleRegisterReceiver(IIntentReceiver receiver, Intent intent, ...) {
receiver.performReceiver(intent, resultCode, dataStr, ...);
}
public void performReceiver(Intent intent, int resultCode, String data, ...) {
ReceiverDispatcher rd = mDispatcher.get();
rd.performReceive(intent, resultCode, data, extras, ...);
}
public void performReceive(Intent intent, int resultCode, ...) {
Args args = new Args(intent, resultCode, data, ...);
mActivityThread.post(args);
}
// ReceiverDispatcher 的内部类
class Args implements Runnable {
public void run() {
final BoradcastReceiver receiver = mReceiver;
receiver.setPendingResult(this);
receiver.onReceive(mContext, intent);
if(receiver.getPendingResult()!=null){
finish();
}
}
}
public final void finish(){
// 静态广播
if(mType == TYPE_COMPONENT) {
final IActivityManager mgr = ActivityManagerNative.getDefault();
if(QueuedWork.hasPendingwork()) {
QueuedWork.singleThreadExecutor().execute(new Runnable(){
public void run(){
sendFinished(mgr);
}
})
}else{
sendFinished(mgr);
}
}else if(mOrderedHint && mType!=TYPE_UNREGISTERED){
IActivityManager mgr = ActivityManagerNative.getDefault();
sendFinished(mgr);
}
// 动态广播什么都没做
}
```
#### 总结
1. 注册广播封装了一个 binder 对象到 AMS
2. 通过广播 intent 找到匹配的 receiver,然后分发
3. 普通动态广播在系统端是并行分发,应用端串行分发
Loading…
Cancel
Save