正文
Watchdog.getInstance().start();
TAG: HandlerChecker
上面的代码中有个比较重要的类,
HandlerChecker
,这是Watchdog用来检测主线程,io线程,显示线程,UI线程的机制,代码也不长,直接贴出来吧。其原理就是通过各个Handler的looper的
MessageQueue
来判断该线程是否卡住了。当然,该线程是运行在SystemServer进程中的线程。
public final class HandlerChecker implements Runnable {88 private final Handler mHandler;89 private final String mName;90 private final long mWaitMax;91 private final ArrayList<Monitor> mMonitors = new ArrayList<Monitor>();92 private boolean mCompleted;93 private Monitor mCurrentMonitor;94 private long mStartTime;9596 HandlerChecker(Handler handler, String name, long waitMaxMillis) {97 mHandler = handler;98 mName = name;99 mWaitMax = waitMaxMillis;100 mCompleted = true;101 }102103 public void addMonitor(Monitor monitor) {104 mMonitors.add(monitor);105 }106 // 记录当前的开始时间107 public void scheduleCheckLocked() {108 if (mMonitors.size() == 0 && mHandler.getLooper().getQueue().isPolling()) {109 // If the target looper has recently been polling, then110 // there is no reason to enqueue our checker on it since that111 // is as good as it not being deadlocked. This avoid having112 // to do a context switch to check the thread. Note that we113 // only do this if mCheckReboot is false and we have no114 // monitors, since those would need to be executed at this point.115 mCompleted = true;116 return;117 }118119 if (!mCompleted) {120 // we already have a check in flight, so no need121 return;122 }123124 mCompleted = false;125 mCurrentMonitor = null;126 mStartTime = SystemClock.uptimeMillis();127 mHandler.postAtFrontOfQueue(this);128 }129130 public boolean isOverdueLocked() {131 return (!mCompleted) && (SystemClock.uptimeMillis() > mStartTime + mWaitMax);132 }133 // 获取完成时间标识134 public int getCompletionStateLocked() {135 if (mCompleted) {136 return COMPLETED;137 } else {138 long latency = SystemClock.uptimeMillis() - mStartTime;139 if (latency < mWaitMax/2) {140 return WAITING;141 } else if (latency < mWaitMax) {142 return WAITED_HALF;143 }144 }145 return OVERDUE;146 }147148 public Thread getThread() {149 return mHandler.getLooper().getThread();150 }151152 public String getName() {153 return mName;154 }155156 public String describeBlockedStateLocked() {157 if (mCurrentMonitor == null) {158 return "Blocked in handler on " + mName + " (" + getThread().getName() + ")";159 } else {160 return "Blocked in monitor " + mCurrentMonitor.getClass().getName()161 + " on " + mName + " (" + getThread().getName() + ")";162 }163 }164165 @Override166 public void run() {167 final int size = mMonitors.size();168 for (int i = 0 ; i < size ; i++) {169 synchronized (Watchdog.this) {170 mCurrentMonitor = mMonitors.get(i);171 }172 mCurrentMonitor.monitor();173 }174175 synchronized (Watchdog.this) {176 mCompleted = true;177 mCurrentMonitor = null;178 }179 }180 }