其他分享
首页 > 其他分享> > Android-怎么就不卡了呢之Choreographer,flutter蓝牙

Android-怎么就不卡了呢之Choreographer,flutter蓝牙

作者:互联网

mFrame = frame;
Message msg = Message.obtain(mHandler, this);
msg.setAsynchronous(true);//Message设置为异步
mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);
}
@Override
public void run() {
mHavePendingVsync = false;
doFrame(mTimestampNanos, mFrame);
}
}

接收到垂直同步信号后回调onVsync方法,这个方法使用handler发送带callback(Runnable类型,自身已继承)的message,最后run()中也是调用doFrame();(关于这个handler的这个操作详细信息逻辑,参照下面本文附录一 handler 分发message

这个message设置为了异步 (msg.setAsynchronous(true);)这意味这他有优先执行的权利,他是怎么被优先执行的呢?参照附录三 message的异步模式

综上,添加callback流程

二、执行

doFrame

void doFrame(long frameTimeNanos, int frame) {
final long startNanos;
synchronized (mLock) {
if (!mFrameScheduled) {
return; // no work to do
}

//当前时间
startNanos = System.nanoTime();
//当前时间和垂直同步时间
final long jitterNanos = startNanos - frameTimeNanos;
//垂直同步时间和当前时间的差值如果大于一个周期就修正一下
if (jitterNanos >= mFrameIntervalNanos) {
//取插值和始终周期的余数
final long lastFrameOffset = jitterNanos % mFrameIntervalNanos;
//当前时间减去上一步得到的余数当作最新的始终信号时间
frameTimeNanos = startNanos - lastFrameOffset;
}
//垂直同步时间上一次时间还小,就安排下次垂直,直接返回
if (frameTimeNanos < mLastFrameTimeNanos) {
scheduleVsyncLocked();
return;
}
mFrameInfo.setVsync(intendedFrameTimeNanos, frameTimeNanos);
mFrameScheduled = false;
mLastFrameTimeNanos = frameTimeNanos;
}

try {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, “Choreographer#doFrame”);
AnimationUtils.lockAnimationClock(frameTimeNanos / TimeUtils.NANOS_PER_MS);

mFrameInfo.markInputHandlingStart();
doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos);

mFrameInfo.markAnimationsStart();
doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos);

mFrameInfo.markPerformTraversalsStart();
doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);

doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos);
} finally {
AnimationUtils.unlockAnimationClock();
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}

if (DEBUG_FRAMES) {
final long endNanos = System.nanoTime();
Log.d(TAG, "Frame " + frame + ": Finished, took "

  1. 第一步修正判断
  1. 第二步‍执行callback callback的执行顺序是:

2.2 doCallbacks();

取出需要被执行的Actions

Action包装在CallbackRecord中,是一个单向列表,按照时间的大小顺序排列的。 取出待执行的Actions是通过CallBackQueue的extractDueCallbacksLocked()方法,可以把CallBackQueue看做是CallBack的管理类,其中还包括添加Action addCallbackLocked(),移除Action removeCallbacksLocked(),是否有带起的Anction hasDueCallbacksLocked()方法。

private final class CallbackQueue {
//链表头
private CallbackRecord mHead;
//是否存在已经到期的Action
public boolean hasDueCallbacksLocked(long now) {
return mHead != null && mHead.dueTime <= now;
}
//获取已经到期的Action
public CallbackRecord extractDueCallbacksLocked(long now) {

return callbacks;
}

//添加Action
public void addCallbackLocked(long dueTime, Object action, Object token) {

}
//移除Action
public void removeCallbacksLocked(Object action, Object token) {

}
}

执行Action

for (CallbackRecord c = callbacks; c != null; c = c.next) {
c.run(frameTimeNanos);
}

从callback中遍历出CallBcakRecord,挨个执行。

三、小结

附一、关于handler执行Message

下面是handler分发逻辑,Looper在MessageQueue得到要执行的message之后就会交给message的target(Handler类型)属性处理msg.target.dispatchMessage(msg);;

public void dispatchMessage(Message msg) {
//当msg的callback不为空的时候直接执行msg的callback它是一个Runnable对象
if (msg.callback != null) {
handleCallback(msg);
} else {
//然后再交给mCallBack,它是handler的一个属性,
//创建Handler的时候可以选择传入一个CallBack对象
//当callBack中handleMessage返回true的时候表示:True if no further handling is desired(不需要进一步处理)

if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
//当mCallback处理返回为false的时候才去执行Handler自身的handleMessage()方法
handleMessage(msg);
}
}

关键逻辑在已注释,小结一下 handler的执行分发Message逻辑

  1. 如果message的callback(runnable)属性不为空,调用这个runable的run()方法执行

private static void handleCallback(Message message) {
message.callback.run();
}

当我们使用handler.post(Runnable r)方法时候就是将r设置给message的callback

  1. 上述条件不满足的情况下,如果handler自身的mCallback不为空的时候就会,将message交给mCallback处理,handlerMessage()结束。这个属性是在handler创建的时候传入的。mCallback是CallBack类型,他是handler的一个内部接口。

public interface Callback {
boolean handleMessage(Message msg);
}

3.当messaga 的callBak为空,且handler的mCallBack为空的时候就交给自己的handlerMessage()方法执行了。我们在自定义handler的时候可以重写这个方法对message进行相应的操作。

附二 、mFrameScheduled属性作用

void doFrame(long frameTimeNanos, int frame) {
final long startNanos;
synchronized (mLock) {
if (!mFrameScheduled) {
return; // no work to do
}


mFrameScheduled = false;

}

附三、Handler机制的异步模式

作用

“异步模式”的作用就是优先,asynchronous 的message在异步模式下有优先执行的权。

用法

MessageQueue使用postSyncBarrier()方法添加屏障,removeSyncBarrier()方法移除屏障这个两个方法是成对使用的。

实现原理

Message next() {

for (;

标签:不卡,Choreographer,frameTimeNanos,CALLBACK,handler,msg,Android,callback,message
来源: https://blog.csdn.net/m0_66155658/article/details/122537587