BlockCanary源码原理
1.BlockCanary.install(this, AppBlockCanaryContext()).start()
开启监听
<p>public void start() {
if (!mMonitorStarted) {
mMonitorStarted = true;
<strong>Looper.getMainLooper().setMessageLogging(mBlockCanaryCore.monitor);</strong>
}
}</p>
<p>public void setMessageLogging(@Nullable Printer printer) {
<strong>mLogging = printer;</strong>
}</p>
<p>public static void loop() {
......
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}</p>
<pre><code> // This must be in a local variable, in case a UI event sets the logger
**final Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
......
msg.target.dispatchMessage(msg);
if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}
......**
} }
基本思路就是通过计算msg的任务的时间,来检测卡顿,看看怎么定位的
LooperMonitor.java @Override public void println(String x) { if (mStopWhenDebugging && Debug.isDebuggerConnected()) { return; } if (!mPrintingStarted) { mStartTimestamp = System.currentTimeMillis(); mStartThreadTimestamp = SystemClock.currentThreadTimeMillis(); mPrintingStarted = true; startDump(); } else { final long endTime = System.currentTimeMillis(); mPrintingStarted = false; if (isBlock(endTime)) { notifyBlockEvent(endTime); } stopDump(); } } 检测时间是1s
private void startDump() { if (null != BlockCanaryInternals.getInstance().stackSampler) { BlockCanaryInternals.getInstance().stackSampler.start(); }
if (null != BlockCanaryInternals.getInstance().cpuSampler) {
BlockCanaryInternals.getInstance().cpuSampler.start();
}
}
public void start() { if (mShouldSample.get()) { return; } mShouldSample.set(true);
HandlerThreadFactory.getTimerThreadHandler().removeCallbacks(mRunnable);
HandlerThreadFactory.getTimerThreadHandler().postDelayed(mRunnable,
BlockCanaryInternals.getInstance().getSampleDelay());
}
延迟时间是800毫秒,
private Runnable mRunnable = new Runnable() { @Override public void run() { doSample();
if (mShouldSample.get()) {
HandlerThreadFactory.getTimerThreadHandler()
.postDelayed(mRunnable, mSampleInterval);
}
}
};
@Override protected void doSample() { StringBuilder stringBuilder = new StringBuilder();
for (StackTraceElement stackTraceElement : **mCurrentThread.getStackTrace()**) {
stringBuilder
.append(stackTraceElement.toString())
.append(BlockInfo.SEPARATOR);
}
synchronized (sStackMap) {
if (sStackMap.size() == mMaxEntryCount && mMaxEntryCount > 0) {
sStackMap.remove(sStackMap.keySet().iterator().next());
}
**sStackMap.put(System.currentTimeMillis(), stringBuilder.toString());**
}
}
评论区