Android Asynchronous Message(异步消息)

构造一个异步消息

  1. Message.setAsynchronous(true)

Sync Barrier

SyncBarrier是通过MessageQueue中的postSyncBarrier(long when)、removeSyncBarrier(int token)调用来实现添加、删除的,用于控制异步消息的执行。

MessageQueue.next()

  1. class MessageQueue {

  2. Message next() {

  3. // ...

  4. // Try to retrieve the next message. Return if found.

  5. final long now = SystemClock.uptimeMillis();

  6. Message prevMsg = null;

  7. Message msg = mMessages;

  8. if (msg != null && msg.target == null) {

  9. // Stalled by a barrier. Find the next asynchronous message in the queue.

  10. do {

  11. prevMsg = msg;

  12. msg = msg.next;

  13. } while (msg != null && !msg.isAsynchronous());

  14. }

  15. // ...

  16. }

  17. }

Looper在获取下一个Message时,如果在队列头部遇到一个SyncBarrier时,则直接跳过后面的同步Message,直奔下一个异步消息。

使用

SyncBarrier在ViewRootImpl执行Traversals相关的代码时有被设置。

当设置一个View属性时,会逐层向上调用到ViewRootImpl.invalidate,从而调用scheduleTraversals,其中设置了一个SyncBarrier。

之后由Vsync信号发送的用于遍历View(重新布局和绘制)的异步消息会高优先级执行。这个一步消息在执行doTraversal时,则将SyncBarrier再移除掉。

  1. class ViewRootImpl {

  2. final class TraversalRunnable implements Runnable {

  3. @Override

  4. public void run() {

  5. doTraversal();

  6. }

  7. }

  8. final TraversalRunnable mTraversalRunnable = new TraversalRunnable();

  9. void scheduleTraversals() {

  10. if (!mTraversalScheduled) {

  11. mTraversalScheduled = true;

  12. mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();

  13. mChoreographer.postCallback(

  14. Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);

  15. if (!mUnbufferedInputDispatch) {

  16. scheduleConsumeBatchedInput();

  17. }

  18. notifyRendererOfFramePending();

  19. pokeDrawLockIfNeeded();

  20. }

  21. }

  22. void unscheduleTraversals() {

  23. if (mTraversalScheduled) {

  24. mTraversalScheduled = false;

  25. mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);

  26. mChoreographer.removeCallbacks(

  27. Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);

  28. }

  29. }

  30. void doTraversal() {

  31. if (mTraversalScheduled) {

  32. mTraversalScheduled = false;

  33. mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);

  34. if (mProfile) {

  35. Debug.startMethodTracing("ViewAncestor");

  36. }

  37. performTraversals();

  38. if (mProfile) {

  39. Debug.stopMethodTracing();

  40. mProfile = false;

  41. }

  42. }

  43. }

  44. }

参考:《Android源码分析之Message》
http://www.cnblogs.com/zhaoxiaowei/p/3660245.html

扩展阅读:《Android Project Butter分析》 http://blog.csdn.net/innost/article/details/8272867