赞
踩
上一篇我们对Service类型的ANR做了介绍,本篇我们将集合源码,对四种ANR类型中的Broadcast Timeout类型的触发机制做详尽的介绍。
在ActivityManagerService 中,构造了两种Broadcast timeout,分别是 前台FG 10s和
后台BG 60s.
mFgBroadcastQueue/mBgBroadcastQueue ⽤来表示foreground和background
⼴播队列.
⾸先看下如下⼏个数据的定义:
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
// How long we allow a receiver to run before giving up on it.
static final int BROADCAST_FG_TIMEOUT = 10*1000;
static final int BROADCAST_BG_TIMEOUT = 60*1000;
mFgBroadcastQueue = new BroadcastQueue(this, mHandler, "foreground",
BROADCAST_FG_TIMEOUT, false);
mBgBroadcastQueue = new BroadcastQueue(this, mHandler, "background",
BROADCAST_BG_TIMEOUT, true);
//frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java /** * Lists of all active broadcasts that are to be executed immediately * (without waiting for another broadcast to finish). Currently this only * contains broadcasts to registered receivers, to avoid spinning up * a bunch of processes to execute IntentReceiver components. Background- * and foreground-priority broadcasts are queued separately. */ /** * 并⾏⼴播队列,可以⽴刻执⾏,⽽⽆需等待另⼀个⼴播运⾏完成,该队列只允 许动态已注册的⼴播, * 从⽽避免发⽣同时拉起⼤量进程来执⾏⼴播,前台的和后台的⼴播分别位于独 ⽴的队列。 */ final ArrayList<BroadcastRecord> mParallelBroadcasts = new ArrayList<>(); /** * List of all active broadcasts that are to be executed one at a time. * The object at the top of the list is the currently activity broadcasts; * those after it are waiting for the top to finish. As with parallel * broadcasts, separate background- and foreground-priority queues are * maintained. */ /** *有序⼴播队列,同⼀时间只允许执⾏⼀个⼴播,该队列顶部的⼴播便是活动⼴ 播, *其他⼴播必须等待该⼴播结束才能运⾏,和并⾏⼴播队列⼀样也是独⽴区别前 台的和后台的⼴播。 */ final ArrayList<BroadcastRecord> mOrderedBroadcasts = new ArrayList<>();
调⽤ processNextBroadcast来处理⼴播.其流程为先处理并⾏⼴播,再处理当前有序
⼴播,最后获取并处理下条有序⼴播.
//frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java
BroadcastQueue(ActivityManagerService service, Handler handler,
String name, long timeoutPeriod, boolean
allowDelayBehindServices) {
mService = service;
mHandler = new BroadcastHandler(handler.getLooper());
mQueueName = name;
mTimeoutPeriod = timeoutPeriod;
mDelayBehindServices = allowDelayBehindServices;
}
processNextBroadcast 最终会调⽤processNextBroadcastLocked (fromMsg
=false).
此处mService为ActivityManagerService,整个流程还是⽐较⻓的,全程持有AMS
锁,这个⽅法⽐较⻓,我省略的部分不在这⾥重点关注的部分.所以⼴播的队列很⻓的
话,直接会严重影响这个⼿机的性能与流畅度,这⾥可以做⼀个监控,看看系统处理⼴
播都需要hold 多久的ams lock.
整个processNextBroadcast的流程⼤致分为下⾯⼏个步骤:
final void processNextBroadcast(boolean fromMsg) { synchronized (mService) { processNextBroadcastLocked(fromMsg, false); } } final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) { BroadcastRecord r; //...省略 //【1】处理并⾏⼴播 mParallelBroadcasts while (mParallelBroadcasts.size() > 0) { r = mParallelBroadcasts.remove(0); r.dispatchTime = SystemClock.uptimeMillis(); r.dispatchClockTime = System.currentTimeMillis(); final int N = r.receivers.size(); for (int i=0; i<N; i++) { Object target = r.receivers.get(i); //分发⼴播给已注册的receiver deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i); } //添加⼴播历史统计 addBroadcastToHistoryLocked(r); } // Now take care of the next serialized one... // mPendingBroadcast正常情况下是空的,如果不是空,说明当前有需 要处理的⼴播,⼀般只有在 // 等待⽬标进程启动来处理对应的⼴播的情况下会出现,这个情况下就仅 仅检查进程是否存在. if (mPendingBroadcast != null) { boolean isDead; if (mPendingBroadcast.curApp.pid > 0) { synchronized (mService.mPidsSelfLocked) { ProcessRecord proc = mService.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。