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