在Android中绘图中,线程可以使用postOnAnimation函数,用于在系统进行下一次动画操作时,运行当前的线程,postOnAnimation(this):

public void postOnAnimation(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
attachInfo.mViewRootImpl.mChoreographer.postCallback(
Choreographer.CALLBACK_ANIMATION, action, null);
} else {
// Assume that post will succeed later
ViewRootImpl.getRunQueue().post(action);
}
}

只看attachInfo不为空的情况,会执行if里面的语句,可以看到属性的Choreographer,看一下Choreographer的postCallback:

public void postCallback(int callbackType, Runnable action, Object token) {
postCallbackDelayed(callbackType, action, token, 0);
}

postCallbackDelayed:

public void postCallbackDelayed(int callbackType,
Runnable action, Object token, long delayMillis) {
if (action == null) {
throw new IllegalArgumentException("action must not be null");
}
if (callbackType < 0 || callbackType > CALLBACK_LAST) {
throw new IllegalArgumentException("callbackType is invalid");
}

postCallbackDelayedInternal(callbackType, action, token, delayMillis);
}

可见最终的实现是在postCallbackDelayedInternal里面,看一下postCallbackDelayedInternal的代码

private void postCallbackDelayedInternal(int callbackType,
Object action, Object token, long delayMillis) {
if (DEBUG) {
Xlog.d(TAG, "PostCallback: type=" + callbackType
+ ", action=" + action + ", token=" + token
+ ", delayMillis=" + delayMillis + ",this = " + this);
}
synchronized (mLock) {
final long now = SystemClock.uptimeMillis();
final long dueTime = now + delayMillis;
mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);

if (dueTime <= now) {
scheduleFrameLocked(now);
} else {
Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_CALLBACK, action);
msg.arg1 = callbackType;
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, dueTime);
}
}
}

可以看到在postCallbackDelayedInternal里,在mCallbackQueues队列里面的callbackType添加一个元素。mCallbackQueues是一个CallbackQueue,从命名里就可以看出现,是一个用于回调的队列,并且是安时间先后顺序排好的,与闹钟原理一样,并且里面有一个CallbackRecord类,记录回调相关的信息。callbackType的类型有三种:CALLBACK_INPUT、CALLBACK_ANIMATION、CALLBACK_TRAVERSAL,这里我们用的是CALLBACK_ANIMATION。在postOnAnimation没有delay,所以只要收到Vsync信号,便立即会被执行。当有Vsync到来是,会执行doFrame,doFrame里有:

...

doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos);
doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos);
doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);

doCallbacks里面有如下语句:

...

callbacks = mCallbackQueues[callbackType].extractDueCallbacksLocked(now);

...

try {
for (CallbackRecord c = callbacks; c != null; c = c.next) {
if (DEBUG) {
Xlog.d(TAG, "RunCallback: type=" + callbackType
+ ", action=" + c.action + ", token=" + c.token
+ ", latencyMillis=" + (SystemClock.uptimeMillis() - c.dueTime)
+ ",this = " + this);
}
c.run(frameTimeNanos);
}
} finally {

...

doCallbacks遍历postCallbackDelayedInternal里面添加的元素,并执行元素里的run函数,整个流程也就跑了一遍。

更多相关文章

  1. android 手机虚拟按键 震动过程的追溯(1)
  2. Android(安卓)之 远程图片获取和本地缓存
  3. 【Android】树形菜单、扩展下拉菜单BaseExpandableListAdapter、
  4. Android(安卓)Touch事件
  5. Android使用MediaCodec将摄像头采集的视频编码为h264
  6. 【Appium + Python3】之安卓8.1,使用xpath定位不到元素
  7. Android(安卓)浅析 EventBus (一) 使用
  8. 走进Java Android(安卓)的线程世界
  9. Android(安卓)消息传递机制 - Looper/Handler/MessageQueue/Mess

随机推荐

  1. Android中shape的使用
  2. android fragment android.support.v4.ap
  3. android 数据库操作 (非ContentProvider)
  4. android java 分享功能实现,Cocos2d-x3.3
  5. Ubuntu上adb找不到设备问题小结
  6. 关于 Android(安卓)进程保活,你所需要知道
  7. Android(安卓)Touch事件传递机制解析
  8. android init进程--init.rc解析过程与执
  9. 深入理解Android工程的编译过程
  10. 【Android】Android(安卓)Studio 使用第