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

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

@ -0,0 +1,217 @@
---
静态广播的注册和收发原理
---
```java
//...
else if(tagName.equals("receiver")) {
// class Activity extends Component<ActivityIntentInfo>{}
Activity a = parseActivity(owner, res, parser, attrs, flags, ...);
owner.receivers.add(a);
}
```
#### 广播的发送
```java
@Override
public void sendBroadcast(Intent intent) {
ActivityManagerNative.getDrfault().broadcastIntent(mMainThread.getApplicationThread(), intent, ...);
}
int broadcastIntent(IApplicationThread caller, Intent intent, ...) {
int res = broadcastIntentLocked(callerApp, ...);
return res;
}
int broadcastIntentLocked(ProcessRecord callerApp, ...) {
// 找静态注册的 receiver
List receivers = collectReceiverComponents(intent, resolvedType, ...);
// 找动态注册的 receiver
List registeredReceivers = mReceiverResolver.queryIntent(intent, ...);
if(!ordered && registeredReceivers.size()>0) {
// 处理动态 receiver,加到并行分发队列
}
// 给没有处理完的动态 receiver,跟静态 receiver 合并到一起
if((receivers != null && receivers.size() > 0)){
// 处理剩下的 receiver,加到串行分发队列
BroadcastQueue queue = boradcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, ...);
queue.enqueueOrderedBroadcastLocked(r);
queue.scheduleBroadcast();
}
return ActivityManager.BROADCAST_SUCCESS;
}
final void processNextBroadcast(boolean formMsg){
// 先给并行分发的广播分发完,然后接下来分发串行广播
// 如果有 pending 的广播,就先直接返回,这个广播在等待应用进程启动
// 如果当前广播分发超时了,就废弃这个广播,处理下一个广播
// 如果没有超时,并且正在分发中,就先返回,什么也不做
// 如果当前的广播已经分发完一个 receive 了,就继续分发下一个 receive
// 如果这个 receive 是动态注册的 receive,就直接分发
// 如果这个 receive 是静态注册的 receive,就先看进程启动没有
// 如果进程启动了,就直接分发
// 没启动的话就先启动进程,然后给广播标记为 pending
// 进程启动后 attachApplication 时继续处理这个 pending 的广播
}
// 超时
do{
r = mOrderedBroadcasts.get(0);
if(now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers)){
// 超时善后工作
boradcastTimeoutLocked(false);
forceReceive = true;
r.state = BroadcastRecord.IDLE;
}
if(r.state != BroadcastRecord.IDLE){
return;
}
if(r.receivers == null || r.nextReceiver >= numReceivers || forceReceive) {
cancelBroadcastTimeoutLocked();
mOrderBroadcasts.remove(0);
continue;
}
} while(r == null);
final void boradcastTimeoutLocked(boolean fromMsg) {
BroadcastRecord r = mOrderedBroadcasts.get(0);
Object curReceiver = r.receivers.get(r.nextReceiver - 1);
// 找到当前分发的 receiver 对应的进程
if(mPendingBroadcast == r){
mPendingBroadcast = null;
}
finishReceiverLocked(r, r.resultCode, ...);
scheduleBroadcastsLocked();
mHandler.post(new AppNotResponding(app, anrMessage));
}
// 没有超时的情况
int recldx = r.nextReceiver++;
r.receiverTime = SystemClock.uptimeMillis();
if(recldx == 0){
r.dispatchTime = r.receiverTime;
r.dispatchClockTime = System.currentTimeMillis();
}
if(!mPendingBroadcastTimeoutMessage) {
long timeoutTime = r.receiverTime + mTimeoutPeriod;
setBroadcastTimeoutLocked(timeoutTime);
}
final Object nextReceiver = r.receivers.get(index);
if(nextReceiver instanceof BroadcastFilter) {
// 如果是动态 receiver,直接分发
BroadcastFilter filter = (BroadcastFilter)nextReceiver;
deliverToRegisterReceiverLocked(r, filter, r.ordered);
return;
}
// 静态 receiver,分发之前先判断进程是否已经启动
r.state = BroadcastRecord.APP_RECEIVE;
ProcessRecord app = mService.getProcessRecordLocked(targetProcess, ...);
if(app != null && app.thread != null){
// 进程已经启动,直接分发
processCurBroadcastLocked(r, app);
return;
}
// 启动进程,并且设置 pending 状态
r.curApp = mService.startProcessLocked(targetProcess, ...);
mPendingBroadcast = r;
mPendingBroadcastRecvIndex = recldx;
```
#### 广播的接收
```java
// 动态 receiver
void deliverToRegisteredReceiverLocked(BroadcastRecord r, ...) {
performReceiveLocked(filter.receiverList.app, ...);
if(ordered) {
r.state = BroadcastRecord.CALL_DONE_RECEIVE;
}
}
void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver, ...) {
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode, ...);
}
// 调到应用端处理
void scheduleRegisteredReceiver(){
final BroadcastReceiver receiver = mReceiver;
final boolean ordered = mOrdered;
final Intent intent = mCurIntent;
mCurIntent = null;
receiver.setPendingResult(this);
receiver.onReceive(mContext, intent);
if(receiver.getPendingResult() != null){
finish();
}
}
// 通知 AMS 广播已经分发完了
void finish(){
IActivityManager mgr = ActivityManagerNative.getDefault();
mgr.finishReceiver(...);
}
void finishReceiver(IBinder who, int resultCode, ...) {
boolean doNext = false;
BroadcastRecord r = queue.getMatchingOrderedReceiver(who);
doNext = r.queue.finishReceiverLocked(r, resultCode, ...);
if(doNext){
r.queue.processNextBroadcast(false);
}
}
public boolean finishReceiverLocked(BroadcastRecord r, ...) {
final int state = r.state;
return state == BroadcastRecord.APP_RECEIVE
|| state == BroadcastRecord.CALL_DONE_RECEIVE;
}
```
静态 receiver 分发:
```java
void processCurBroadcastLocked(BroadcastRecord r, ...) {
r.receiver = app.thread.asBinder();
r.curApp = app;
app.curReceiver = r;
app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver, ...);
}
void scheduleReceiver(Intent intent, ActivityInfo info, ...) {
ReceiverData r = new ReceiverData(intent, resultCode, data, ...);
r.info = info;
r.compatInfo = compatInfo;
sendMessage(H.RECEIVER, r);
}
private void handleReceiver(ReceiverData data) {
LoadedApk pakcageInfo = getPackageInfoNoCheck(...);
BroadcastReceiver receiver;
receiver = cl.loadClass(component).newInstance();
Application app = packageInfo.makeApplication(false, ...);
ContextImpl context = app.getBaseContext();
receiver.setPendingResult(data);
receiver.onReceive(context.getReceiverRestrictedContext(), data.intent);
if(receiver.getPendingResult() != null) {
data.finish();
}
}
```
应用进程启动之后,向 AMS 报告,然后启动 pengdingBroadcast:
```java
boolean attachApplicationLocked(IApplicationThread thread, ...) {
sendPendingBroadcastsLocked(app);
}
boolean sendPendingBroadcastsLocked(ProcessRecord app) {
for(BroadcastQueue queue : mBroadcastQueues){
queue.sendPendingBroadcastsLocked(app);
}
}
boolean sendPendingBroadcastsLocked(ProcessRecord app) {
final BroadcastRecord br = mPendingBroadcast;
if(br != null && br.curApp.pid == app.pid) {
mPendingBroadcast = null;
processCurBroadcastLocked(br, app);
}
}
```
#### 说说静态广播的注册和收发原理
1. 静态广播是怎么注册的
2. 静态广播是串行分发的
3. 静态广播的生命周期及上下文
Loading…
Cancel
Save