parent
dea21c9edb
commit
e2e9da9a43
@ -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…
Reference in new issue