使用方式如下:
//Application.javapublic void onCreate() { super.onCreate(); //在Application中使用postFrameCallback Choreographer.getInstance().postFrameCallback(new FPSFrameCallback(System.nanoTime()));}public class FPSFrameCallback implements Choreographer.FrameCallback { private static final String TAG = "FPS_TEST"; private long mLastFrameTimeNanos = 0; private long mFrameIntervalNanos; public FPSFrameCallback(long lastFrameTimeNanos) { mLastFrameTimeNanos = lastFrameTimeNanos; mFrameIntervalNanos = (long)(1000000000 / 60.0); } @Override public void doFrame(long frameTimeNanos) { //初始化时间 if (mLastFrameTimeNanos == 0) { mLastFrameTimeNanos = frameTimeNanos; } final long jitterNanos = frameTimeNanos - mLastFrameTimeNanos; if (jitterNanos >= mFrameIntervalNanos) { final long skippedFrames = jitterNanos / mFrameIntervalNanos; if(skippedFrames>30){ //丢帧30以上打印日志 Log.i(TAG, "Skipped " + skippedFrames + " frames! " + "The application may be doing too much work on its main thread."); } } mLastFrameTimeNanos=frameTimeNanos; //注册下一帧回调 Choreographer.getInstance().postFrameCallback(this); }}UI绘制全路径分析:
4.Trace System Calls:捕捉细粒度的详细信息,使您可以查抄应用步调与体系资源的交互方式 您可以查抄线程状态简直切时间和连续时间,可视化CPU瓶颈在全部内核中的位置,并添加自定义跟踪变乱举行分析。在对性能标题举行故障清除时,此类信息大概至关紧张。要使用此设置,您必须将应用步调摆设到运行Android 7.0(API级别24)或更高版本的装备。
起首,我们看下Looper用于实验消息循环的loop()方法,关键代码如下所示:
/** * Run the message queue in this thread. Be sure to call * {@link #quit()} to end the loop. */public static void loop() { ... for (;;) { Message msg = queue.next(); // might block if (msg == null) { // No message indicates that the message queue is quitting. return; // This must be in a local variable, in case a UI event sets the logger final Printer logging = me.mLogging; if (logging != null) { // 1 logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); } ... try { // 2 msg.target.dispatchMessage(msg); dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0; } finally { if (traceTag != 0) { Trace.traceEnd(traceTag); } } ... if (logging != null) { // 3 logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); }在Looper的loop()方法中,在实在行每一个消息(解释2处)的前后都由logging举行了一次打印输出。可以看到,在实验消息前是输出的">>>>> Dispatching to ",在实验消息后是输出的"<<<<< Finished to ",它们打印的日志是不一样的,我们就可以由此来判断消息实验的前后时间点。 详细的实现可以归纳为如下步调:
// 留意在主进程初始化调用BlockCanary.install(this, new AppBlockCanaryContext()).start();
3.继承BlockCanaryContext类去实现自己的监控设置上下文类
public class AppBlockCanaryContext extends BlockCanaryContext { ... ... /** * 指定判断为卡顿的阈值threshold (in millis), * 你可以根据差别装备的性能去指定差别的阈值 * * @return threshold in mills */ public int provideBlockThreshold() { return 1000; } ....}