Andriod Handler 分析

Handler

Handler典型使用方法代码分析

典型的Handler的使用方法:

  1. Looper.prepared(); 
  2. Handler handler = new Handler(); 
  3. Looper.loop(); 

Handler 初始化和消息处理流程

Looper的初始化

  1. Class Looper { 
  2. static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>(); 
  3. private static void prepare(boolean quitAllowed)
  4. sThreadLocal.set(new Looper(quitAllowed)); 


  5.  
  6. private Looper(boolean quitAllowed)
  7. //创建Native层的一个Looper 
  8. mQueue = new MessageQueue(quitAllowed); 
  9. mThread = Thread.currentThread(); 

首次建立一个Looper并且将这个Looper与当前Thread连接

Looper的底层实现

Native层的Looper开始于MessageQueue.nativeInit()

  1. NativeMessageQueue::NativeMessageQueue() : 
  2. mPollEnv(NULL), mPollObj(NULL), mExceptionObj(NULL) { 
  3. //调用Native层的Looper 
  4. mLooper = Looper::getForThread(); 
  5. //第一次调用的话,这里的mLooper应该是空的,所以应该从创建一个新的Looper 
  6. if (mLooper == NULL) { 
  7. mLooper = new Looper(false); 
  8. //这里面新建的Looper与当前Thread绑定 
  9. Looper::setForThread(mLooper); 


  10.  
  11. Looper::Looper(bool allowNonCallbacks) : 
  12. mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false), 
  13. mPolling(false), mEpollFd(-1), mEpollRebuildRequired(false), 
  14. mNextRequestSeq(0), mResponseIndex(0), mNextMessageUptime(LLONG_MAX) { 
  15. //首先建立一个fd,用来从epoll中唤醒 
  16. mWakeEventFd = eventfd(0, EFD_NONBLOCK); 
  17. LOG_ALWAYS_FATAL_IF(mWakeEventFd < 0, "Could not make wake event fd. errno=%d", errno); 
  18.  
  19. AutoMutex _l(mLock)
  20. rebuildEpollLocked(); 

  21.  
  22. void Looper::rebuildEpollLocked() { 
  23.  
  24. // Allocate the new epoll instance and register the wake pipe. 
  25. //创建epoll,并且制定epoll大小为8,也就是最多监视8个fd 
  26. mEpollFd = epoll_create(EPOLL_SIZE_HINT); 
  27. LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance. errno=%d", errno); 
  28.  
  29. struct epoll_event eventItem; 
  30. memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union 
  31. eventItem.events = EPOLLIN; 
  32. eventItem.data.fd = mWakeEventFd; 
  33. //首先将mWakeEventFd注册进去 
  34. int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeEventFd, & eventItem); 
  35.  

简单来说就是将这个mWakeEventFd放入到epoll中。

Handler 初始化

  1. public Handler(Callback callback, boolean async)
  2. mLooper = Looper.myLooper(); 
  3. if (mLooper == null) { 
  4. throw new RuntimeException( 
  5. "Can't create handler inside thread that has not called Looper.prepare()"); 

  6. mQueue = mLooper.mQueue; 
  7. mCallback = callback; 
  8. mAsynchronous = async; 

Looper运行

  1. public static void loop()
  2. final Looper me = myLooper(); 
  3.  
  4. final MessageQueue queue = me.mQueue; 
  5. for (;;) { 
  6. Message msg = queue.next(); // might block 
  7.  
  8. msg.target.dispatchMessage(msg); 
  9.  
  10. msg.recycleUnchecked(); 


  11.  
  12. Message next()
  13. for (;;) { 
  14. nativePollOnce(ptr, nextPollTimeoutMillis); 


这个函数最终会调用到Looper.c中的pollOnce函数

  1. int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) { 
  2. result = pollInner(timeoutMillis); 

  3.  
  4. int Looper::pollInner(int timeoutMillis) { 
  5.  
  6. int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis) 
  7.  
  8. for (int i = 0; i < eventCount; i++) { 
  9. int fd = eventItems[i].data.fd; 
  10. uint32_t epollEvents = eventItems[i].events; 
  11. if (fd == mWakeEventFd) { 
  12. if (epollEvents & EPOLLIN) {//如果是mWakeEventFd的话就唤醒这个loop 
  13. awoken(); 
  14. } else
  15.  

  16. } else
  17. //获取对应的event,并且将event放入到reponse队列中。 



Handler 消息的发送

其实Handler的发送消息最终都是调用enqueueMessage
下面看其中的一个函数为例

  1. sendMessage(Message msg)->sendMessageDelayed(Message msg, long delayMillis)->sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis)->enqueueMessage(queue, msg, uptimeMillis) 

那就看一下enqueueMessage是怎么实现的就好了

  1. private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis)
  2. msg.target = this
  3. if (mAsynchronous) { 
  4. msg.setAsynchronous(true); 

  5. return queue.enqueueMessage(msg, uptimeMillis); 

看来就是调用MessageQueue.enqueueMessage()

  1. boolean enqueueMessage(Message msg, long when)
  2.  
  3. msg.markInUse(); 
  4. msg.when = when; 
  5. Message p = mMessages; 
  6. boolean needWake; 
  7. if (p == null || when == 0 || when < p.when) { 
  8. // New head, wake up the event queue if blocked. 
  9. //如果现在没有消息需要处理的话,就将msg插入到队列中 
  10. msg.next = p; 
  11. mMessages = msg; 
  12. needWake = mBlocked; 
  13. } else
  14. // Inserted within the middle of the queue. Usually we don't have to wake 
  15. // up the event queue unless there is a barrier at the head of the queue 
  16. // and the message is the earliest asynchronous message in the queue. 
  17. needWake = mBlocked && p.target == null && msg.isAsynchronous(); 
  18. Message prev; 
  19. for (;;) { 
  20. prev = p; 
  21. p = p.next; 
  22. if (p == null || when < p.when) { 
  23. break

  24. if (needWake && p.isAsynchronous()) { 
  25. needWake = false


  26. msg.next = p; // invariant: p == prev.next 
  27. prev.next = msg; 

  28.  
  29. // We can assume mPtr != 0 because mQuitting is false. 
  30. if (needWake) { 
  31. nativeWake(mPtr); 


  32. return true

这里需要注意的是,只有调用nativeWake这个函数之后,loop才能离开block状态,之后才能处理msg。

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

Andriod Handler 分析

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭