Android Looper和Handler分析

Android应用程序是通过消息来驱动的,每个应用程序都有一个Main looper在ActivityThread中创建。我们这一节中就主要来分析下Looper和Handler的实现机制,首先来简单介绍一下它们的关系:

?Thread、Looper、MessageQueue、Handler的关系

–Thread线程是整个Looper循环执行的场所

–Looper消息泵,不断的从MessageQueue中读取消息并执行,Looper就是一个无限循环,Looper中包含MessageQueue

–MessageQueue消息队列,负责存放消息

–Looper分发消息给Handler执行;Handler同时可以向MessageQueue添加消息

我们通过下面一个简单的程序来看一下如何使用Looper和Handler:

[java] 
view plain
copy

  1. class LooperThread extends Thread {
  2. public Handler mHandler;
  3. public void run() {
  4. Looper.prepare();
  5. mHandler = new Handler() {
  6. public void handleMessage(Message msg) {
  7. // process incoming messages here
  8. }
  9. };
  10. Looper.loop();
  11. }
  12. }

首先在一个Thread中需要先调用Looper.prepare方法去做好初始化工作,其实就是实例化一个MessageQueue。然后调用Looper.loop就可以开始循环了。那我们首先先看一下prepare方法:

[java] 
view plain
copy

  1. public static void prepare() {
  2. prepare(true);
  3. }
  4. private static void prepare(boolean quitAllowed) {
  5. if (sThreadLocal.get() != null) {
  6. throw new RuntimeException("Only one Looper may be created per thread");
  7. }
  8. sThreadLocal.set(new Looper(quitAllowed));
  9. }
  10. private Looper(boolean quitAllowed) {
  11. mQueue = new MessageQueue(quitAllowed);
  12. mThread = Thread.currentThread();
  13. }

可以看到在prepare方法中主要是构造一个Looper对象并存放在sThreadLocal中,sThreadLocal是线程本地存储的变量,每个线程有这么一块区域来存储线程的数据,这些数据不会被进程中其它线程所修改。在Looper的构造函数中实例化一个MessageQueue对象:

[java] 
view plain
copy

  1. MessageQueue(boolean quitAllowed) {
  2. mQuitAllowed = quitAllowed;
  3. mPtr = nativeInit();
  4. }
  5. static jint android_os_MessageQueue_nativeInit(JNIEnv* env, jclass clazz) {
  6. NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue();
  7. if (!nativeMessageQueue) {
  8. jniThrowRuntimeException(env, "Unable to allocate native queue");
  9. return 0;
  10. }
  11. nativeMessageQueue->incStrong(env);
  12. return reinterpret_cast<jint>(nativeMessageQueue);
  13. }

在MessageQueue的构造函数中通过JNI调用到android_os_MessageQueue_nativeInit方法,在这个方法里面,构造一个NativeMessageQueue对象,并在Java层的MessageQueue成员变量mPtrl保存NativeMessageQueue对象的内存地址,以便后面Java层调用NativeMessageQueue的其它方法。我们再来看一下NativeMessageQueue的构造函数:

[java] 
view plain
copy

  1. NativeMessageQueue::NativeMessageQueue() : mInCallback(false), mExceptionObj(NULL) {
  2. mLooper = Looper::getForThread();
  3. if (mLooper == NULL) {
  4. mLooper = new Looper(false);
  5. Looper::setForThread(mLooper);
  6. }
  7. }

在Native层的MessageQueue中,也通过TLS技术在线程中保存是否创建了底层Looper,如果有创建就可以通过getForThread返回;如果没有,getForThread将返回NULL。当然这里肯定会返回NULL,这里就将构造一个Looper对象并设置到这个线程的TLS中。我们来看Looper的构造函数:

[java] 
view plain
copy

  1. Looper::Looper(bool allowNonCallbacks) :
  2. mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false),
  3. mResponseIndex(0), mNextMessageUptime(LLONG_MAX) {
  4. int wakeFds[2];
  5. int result = pipe(wakeFds);
  6. LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe.  errno=%d", errno);
  7. mWakeReadPipeFd = wakeFds[0];
  8. mWakeWritePipeFd = wakeFds[1];
  9. result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);
  10. LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking.  errno=%d",
  11. errno);
  12. result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);
  13. LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking.  errno=%d",
  14. errno);
  15. mIdling = false;
  16. // Allocate the epoll instance and register the wake pipe.
  17. mEpollFd = epoll_create(EPOLL_SIZE_HINT);
  18. LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance.  errno=%d", errno);
  19. struct epoll_event eventItem;
  20. memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
  21. eventItem.events = EPOLLIN;
  22. eventItem.data.fd = mWakeReadPipeFd;
  23. result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & eventItem);
  24. LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance.  errno=%d",
  25. errno);
  26. }

Looper的构造函数比较简单,首先构造一个pipe,一端用于读,另一端用于写。然后使用epoll将它mWakeReadPipeFd添加到mEpollFd中。后面我们就可以通过在mWakeWritePipeFd端写数据,让epoll_wait跳出等待。当这里Looper.prepare函数就介绍完了,我们先来看一下上面说到的几个类的关系图:

然后我们再来分析Looper.loop方法:

[java] 
view plain
copy

  1. public static void loop() {
  2. final Looper me = myLooper();
  3. final MessageQueue queue = me.mQueue;
  4. Binder.clearCallingIdentity();
  5. final long ident = Binder.clearCallingIdentity();
  6. for (;;) {
  7. Message msg = queue.next(); // might block
  8. if (msg == null) {
  9. return;
  10. }
  11. msg.target.dispatchMessage(msg);
  12. final long newIdent = Binder.clearCallingIdentity();
  13. msg.recycle();
  14. }
  15. }

首先myLooper返回ThreadLocal存储的前面构造的Looper对象。然后调用Looper中的MessageQueue的next方法,next方法返回下一个消息(如果有,如果没有就一直等待),当然一般情况下不会返回空消息。并调用msg.target的dispatchMessage方法,这里的target其实就是Handler,我们后面再来分析。先来看一下MessageQueue的next方法:

[java] 
view plain
copy

  1. Message next() {
  2. int pendingIdleHandlerCount = -1; // -1 only during first iteration
  3. int nextPollTimeoutMillis = 0;
  4. for (;;) {
  5. if (nextPollTimeoutMillis != 0) {
  6. Binder.flushPendingCommands();
  7. }
  8. nativePollOnce(mPtr, nextPollTimeoutMillis);
  9. synchronized (this) {
  10. final long now = SystemClock.uptimeMillis();
  11. Message prevMsg = null;
  12. Message msg = mMessages;
  13. if (msg != null && msg.target == null) {
  14. do {
  15. prevMsg = msg;
  16. msg = msg.next;
  17. } while (msg != null && !msg.isAsynchronous());
  18. }
  19. if (msg != null) {
  20. if (now < msg.when) {
  21. nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
  22. } else {
  23. mBlocked = false;
  24. if (prevMsg != null) {
  25. prevMsg.next = msg.next;
  26. } else {
  27. mMessages = msg.next;
  28. }
  29. msg.next = null;
  30. msg.markInUse();
  31. return msg;
  32. }
  33. } else {
  34. nextPollTimeoutMillis = -1;
  35. }
  36. if (mQuitting) {
  37. dispose();
  38. return null;
  39. }
  40. if (pendingIdleHandlerCount < 0
  41. && (mMessages == null || now < mMessages.when)) {
  42. pendingIdleHandlerCount = mIdleHandlers.size();
  43. }
  44. if (pendingIdleHandlerCount <= 0) {
  45. // No idle handlers to run.  Loop and wait some more.
  46. mBlocked = true;
  47. continue;
  48. }
  49. if (mPendingIdleHandlers == null) {
  50. mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
  51. }
  52. mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
  53. }
  54. for (int i = 0; i < pendingIdleHandlerCount; i++) {
  55. final IdleHandler idler = mPendingIdleHandlers[i];
  56. mPendingIdleHandlers[i] = null; // release the reference to the handler
  57. boolean keep = false;
  58. try {
  59. keep = idler.queueIdle();
  60. } catch (Throwable t) {
  61. Log.wtf("MessageQueue", "IdleHandler threw exception", t);
  62. }
  63. if (!keep) {
  64. synchronized (this) {
  65. mIdleHandlers.remove(idler);
  66. }
  67. }
  68. }
  69. pendingIdleHandlerCount = 0;
  70. nextPollTimeoutMillis = 0;
  71. }
  72. }

next函数虽然比较长,但它的逻辑还是比较简单的,主要可以分为下面三个步骤:

?调用nativePollOnce去完成等待。初始值nextPollTimeoutMillis为0,epoll_wait会马上返回,当nextPollTimeoutMillis为-1,epoll_wait会一直等待

?当nativePollOnce返回后,获取mMessages中消息。如果mMessages没有消息,就设置nextPollTimeoutMillis为-1,表示下一次epoll_wait时一直等待。如果mMessages中有消息,并且当前系统时间不小于messge待处理的时间,就返回这个消息

?如果没有消息处理,并且当前有IdleHandlers,就调用IdleHandlers的queueIdle方法,并修改nextPollTimeoutMillis为0。IdleHandlers用于在MessageQueue中没有消息时做回调使用。

在上面的三个步骤中,最重要的当然是nativePollOnce,我们来简单分析一下:

[java] 
view plain
copy

  1. void NativeMessageQueue::pollOnce(JNIEnv* env, int timeoutMillis) {
  2. mInCallback = true;
  3. mLooper->pollOnce(timeoutMillis);
  4. mInCallback = false;
  5. if (mExceptionObj) {
  6. env->Throw(mExceptionObj);
  7. env->DeleteLocalRef(mExceptionObj);
  8. mExceptionObj = NULL;
  9. }
  10. }
  11. int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
  12. int result = 0;
  13. for (;;) {
  14. if (result != 0) {
  15. return result;
  16. }
  17. result = pollInner(timeoutMillis);
  18. }
  19. }
  20. int Looper::pollInner(int timeoutMillis) {
  21. int result = ALOOPER_POLL_WAKE;
  22. mResponses.clear();
  23. mResponseIndex = 0;
  24. // We are about to idle.
  25. mIdling = true;
  26. struct epoll_event eventItems[EPOLL_MAX_EVENTS];
  27. int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
  28. // No longer idling.
  29. mIdling = false;
  30. // Acquire lock.
  31. mLock.lock();
  32. if (eventCount < 0) {
  33. if (errno == EINTR) {
  34. goto Done;
  35. }
  36. ALOGW("Poll failed with an unexpected error, errno=%d", errno);
  37. result = ALOOPER_POLL_ERROR;
  38. goto Done;
  39. }
  40. // Check for poll timeout.
  41. if (eventCount == 0) {
  42. #if DEBUG_POLL_AND_WAKE
  43. ALOGD("%p ~ pollOnce - timeout", this);
  44. #endif
  45. result = ALOOPER_POLL_TIMEOUT;
  46. goto Done;
  47. }
  48. for (int i = 0; i < eventCount; i++) {
  49. int fd = eventItems[i].data.fd;
  50. uint32_t epollEvents = eventItems[i].events;
  51. if (fd == mWakeReadPipeFd) {
  52. if (epollEvents & EPOLLIN) {
  53. awoken();
  54. } else {
  55. }
  56. } else {
  57. }
  58. }
  59. Done: ;
  60. mNextMessageUptime = LLONG_MAX;
  61. mLock.unlock();
  62. return result;
  63. }

因为Native层Looper需要支持底层自己的消息处理机制,所以pollOnce的代码中添加处理底层Message的代码,我们抛开这部分的代码,其实pollOnce就是调用epoll_wait去等待时间发生。当timeoutMillis为0时,它会立即返回;当timeoutMillis为-1时,它会一直等待,知道我们调用Looper::wake方法向mWakeWritePipeFd写入数据。我们简要来看一下上面介绍prepare和loop的流程:

我们再来分析下Handler和Message的关系,并介绍如何向MessageQueue中添加消息,以便epoll_wait能够返回。首先来看Handler的构造函数,Handler有很多构造函数,我们可以把Handler绑定到一个Looper上,也可以不带Looper参数,它会默认的绑定到我们的MainThread中:

[java] 
view plain
copy

  1. public Handler(Callback callback) {
  2. this(callback, false);
  3. }
  4. public Handler(Looper looper) {
  5. this(looper, null, false);
  6. }
  7. public Handler(Callback callback, boolean async) {
  8. mLooper = Looper.myLooper();
  9. if (mLooper == null) {
  10. throw new RuntimeException(
  11. "Can‘t create handler inside thread that has not called Looper.prepare()");
  12. }
  13. mQueue = mLooper.mQueue;
  14. mCallback = callback;
  15. mAsynchronous = async;
  16. }
  17. public Handler(Looper looper, Callback callback, boolean async) {
  18. mLooper = looper;
  19. mQueue = looper.mQueue;
  20. mCallback = callback;
  21. mAsynchronous = async;
  22. }

上面列举了两种Handler的构造方法,它主要从当前Looper中得到MessageQueue对象,并保存在mQueue中,后面我们就可以调用mQueue的方法来添加消息了。来看一下Handler和Message的类图:

来看一下一个简单的sendMessage方法,当然Message对象可以通过Message的静态方法obtain获得:

[java] 
view plain
copy

  1. public final boolean sendMessage(Message msg)
  2. {
  3. return sendMessageDelayed(msg, 0);
  4. }
  5. public final boolean sendMessageDelayed(Message msg, long delayMillis)
  6. {
  7. if (delayMillis < 0) {
  8. delayMillis = 0;
  9. }
  10. return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
  11. }
  12. public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
  13. MessageQueue queue = mQueue;
  14. return enqueueMessage(queue, msg, uptimeMillis);
  15. }
  16. private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
  17. msg.target = this;
  18. if (mAsynchronous) {
  19. msg.setAsynchronous(true);
  20. }
  21. return queue.enqueueMessage(msg, uptimeMillis);
  22. }

这里经过一系列的方法,最终调用到MessageQueue的enqueueMessage函数:

[java] 
view plain
copy

  1. boolean enqueueMessage(Message msg, long when) {
  2. if (msg.target == null) {
  3. throw new AndroidRuntimeException("Message must have a target.");
  4. }
  5. synchronized (this) {
  6. msg.when = when;
  7. Message p = mMessages;
  8. boolean needWake;
  9. if (p == null || when == 0 || when < p.when) {
  10. msg.next = p;
  11. mMessages = msg;
  12. needWake = mBlocked;
  13. } else {
  14. needWake = mBlocked && p.target == null && msg.isAsynchronous();
  15. Message prev;
  16. for (;;) {
  17. prev = p;
  18. p = p.next;
  19. if (p == null || when < p.when) {
  20. break;
  21. }
  22. if (needWake && p.isAsynchronous()) {
  23. needWake = false;
  24. }
  25. }
  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. }
  33. }
  34. return true;
  35. }

enqueueMessage检查mMessages中是否有消息,如果没有,就把它当前头添加到mMessages中,并更新needWake为mBlocked,mBlocked会在mMessages为空并且没有IdleHandlers时置为true,这时timeoutMillis为-1,epoll_wait会无限等待,所以我们需要调用natvieWake唤醒它;如果在mMessages有消息,我们一般情况下不需要调用nativeWake来唤醒,除非我们当前头部是barrier消息(target为NULL)并且待send的消息是第一个异步的,这里就将调用nativeWake来唤醒它。这里注意的是异步消息不会被barrier消息打断,并且异步消息可以在它之前的同步消息之前执行。再来看一下nativeWake函数的实现:

[java] 
view plain
copy

  1. static void android_os_MessageQueue_nativeWake(JNIEnv* env, jclass clazz, jint ptr) {
  2. NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
  3. return nativeMessageQueue->wake();
  4. }
  5. void Looper::wake() {
  6. ssize_t nWrite;
  7. do {
  8. nWrite = write(mWakeWritePipeFd, "W", 1);
  9. } while (nWrite == -1 && errno == EINTR);
  10. if (nWrite != 1) {
  11. if (errno != EAGAIN) {
  12. ALOGW("Could not write wake signal, errno=%d", errno);
  13. }
  14. }
  15. }

这里其实就是向pipe的写端写入一个"W"字符,这样epoll_wait就可以跳出等待了。我们先来看一下上面介绍的sendMessage的流程:

当Message的next方法返回一个消息后,后面就将调用Handler的dispatchMessage去处理它:

[java] 
view plain
copy

  1. public void dispatchMessage(Message msg) {
  2. if (msg.callback != null) {
  3. handleCallback(msg);
  4. } else {
  5. if (mCallback != null) {
  6. if (mCallback.handleMessage(msg)) {
  7. return;
  8. }
  9. }
  10. handleMessage(msg);
  11. }
  12. }

当我们post一个Runnable时,Message的callback就为这个Runnable,如果Runnable不为空,直接调用callback.run方法。如果msg.callback为空,但mCallback不为空,则调用mCallback的handleMessage方法。最后两者都没有的情况下才调用Handler的handleMessage方法,所以我们在程序中一般重载handleMessage来处理消息即可。下面是dispatchMessage的流程图:

我们来看下面这段代码:

[java] 
view plain
copy

  1. class LooperThread extends Thread {
  2. public Looper myLooper = null;
  3. public void run() {
  4. Looper.prepare();
  5. myLooper = Looper.myLooper();
  6. Looper.loop();
  7. }
  8. }
  9. {
  10. LooperThread myLooperThread = new LooperThread();
  11. myLooperThread.start();
  12. Looper mLooper = myLooperThread.myLooper;
  13. Handler mHandler = new Handler(mLooper);
  14. mHandler.sendEmptyMessage(0);
  15. }

这在我们程序中会经常用到,先在一个Thread中准备好Looper,然后使用这个Looper绑定到另外一个Handler上面。但上面的程序有点bug,当myLooperThread还没执行到myLooper = Looper.myLooper()这一行时,主线程接着运行并调用Handler的构造函数,因为此时MessageQueue还没准备好,所以这里会抛出一个异常。为了处理这种问题,Android提供了HandlerThread这个类来完美解决这个问题:

[java] 
view plain
copy

  1. public HandlerThread(String name, int priority) {
  2. super(name);
  3. mPriority = priority;
  4. }
  5. public void run() {
  6. mTid = Process.myTid();
  7. Looper.prepare();
  8. synchronized (this) {
  9. mLooper = Looper.myLooper();
  10. notifyAll();
  11. }
  12. Process.setThreadPriority(mPriority);
  13. onLooperPrepared();
  14. Looper.loop();
  15. mTid = -1;
  16. }
  17. public Looper getLooper() {
  18. if (!isAlive()) {
  19. return null;
  20. }
  21. // If the thread has been started, wait until the looper has been created.
  22. synchronized (this) {
  23. while (isAlive() && mLooper == null) {
  24. try {
  25. wait();
  26. } catch (InterruptedException e) {
  27. }
  28. }
  29. }
  30. return mLooper;
  31. }

通过wait和notifyAll机制完美解决了以上的问题。看来我们在程序中还是要多使用HandlerThread。下面对上面的介绍做一个简单的总结:

?Handler的处理过程运行在创建Handler的线程里

?一个Looper对应一个MessageQueue

?一个线程对应一个Looper

?一个Looper可以对应多个Handler

?当MessageQueue中没有消息时,IdleHandlers会被回调

?MessageQueue中的消息本来是有序的处理,但可以通过barrier消息将其中断(打乱)

时间: 2024-08-01 22:47:53

Android Looper和Handler分析的相关文章

Android Looper和Handler

Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理. Handler:处理者,负责Message的发送及处理.使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等. MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行.当然,存放Message并非实际意义的保存,而是将Message以链表的方

Android looper、handler及HandlerThread

一.简介 在Android开发中,使用消息队列(message)完成线程间通信.而使用消息队列的线程就是消息循环(message looper).消息循环不断的检查消息队列,是否有新消息.消息循环是由一个线程和一个looper组成:looper对象管理着线程的消息队列. Android的主线程也是一个消息循环,也具有一个Looper,主线程所有的任务都是由looper完成.消息循环是由一个线程和一个looper组成,looper对象管理着线程的消息队列:因此,looper不断的从消息队列中抓取消

【Android】Handler、Looper源码分析

一.前言 源码分析使用的版本是 4.4.2_r1. Handler和Looper的入门知识以及讲解可以参考我的另外一篇博客:Android Handler机制 简单而言:Handler和Looper是对某一个线程实现消息机制的重要组成部分,另外两个重要元素是Message和MessageQueue,通过这四个类,可以让某个线程具备接收.处理消息的能力. 二.源码剖析 虽然只有四个类,而且这里只是剖析其中两个,但是也不能独立分析,必须组合进行解析.切入点是类Looper的注释中的一段示例代码: 1

Android消息机制Handler、Looper、MessageQueue源码分析

1. Handler Looper MessageQueue的关系 2.源码分析 下图表示了Handler.Looper.MessageQueue.Message这四个类之间的关系. Handler必须与一个Looper关联,相关Looper决定了该Handler会向哪个MessageQueue发送Message 每一个Looper中都包含一个MessageQueue Handler中的mQueue引用的就是与之关联的Looper的MessageQueue 不管Handler在哪个线程发送Mes

Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38377229 ,本文出自[张鸿洋的博客] 很多人面试肯定都被问到过,请问Android中的Looper , Handler , Message有什么关系?本篇博客目的首先为大家从源码角度介绍3者关系,然后给出一个容易记忆的结论. 1. 概述 Handler . Looper .Message 这三者都与Android异步消息处理线程相关的概念.那么什么叫异步消息处理线程呢?异步

深入源码解析Android中的Handler,Message,MessageQueue,Looper

本文主要是对Handler和消息循环的实现原理进行源码分析,如果不熟悉Handler可以参见博文< Android中Handler的使用>,里面对Android为何以引入Handler机制以及如何使用Handler做了讲解. 概括来说,Handler是Android中引入的一种让开发者参与处理线程中消息循环的机制.我们在使用Handler的时候与Message打交道最多,Message是Hanlder机制向开发人员暴露出来的相关类,可以通过Message类完成大部分操作Handler的功能.但

android的消息处理机制——Looper,Handler,Message

这篇文章有一半是copy别人的,站在巨人的肩膀上,我们才能看得更高更远...... 在开始讨论android的消息处理机制前,先来谈谈一些基本相关的术语. 通信的同步(Synchronous):指向客户端发送请求后,必须要在服务端有回应后客户端才继续发送其它的请求,所以这时所有请求将会在服务端得到同步,直到服务端返回请求. 通信的异步(Asynchronous):指客户端在发送请求后,不必等待服务端的回应就可以发送下一个请求. 所谓同步调用,就是在一个函数或方法调用时,没有得到结果之前,该调用就

Android开发:Handler异步通信机制全面解析(包含Looper、Message Queue

前言 最近刚好在做关于异步通信的需求,那么,今天我们来讲解下Android开发中的Handler异步通信传递机制(包括Looper.Message Queue) 目录 定义 Android提供的一套消息传递机制 作用 用于实现子线程对UI线程的更新,实现异步消息的处理: - 在新启动的线程中发送消息 - 在主线程中获取并处理信息 为什么要用Handler 在安卓开发中: - 为了保证Android的UI操作是线程安全的,Android规定了只允许UI线程修改Activity里的UI组件: - 但

深入理解Android消息处理系统——Looper、Handler、Thread

Android应用程序也是消息驱动的,按道理来说也应该提供消息循环机制.实际上谷歌参考了Windows的消息循环机制,也在Android系统中实现了消息循环机制. Android通过Looper.Handler来实现消息循环机制,Android消息循环是针对线程的(每个线程都可以有自己的消息队列和消息循环). 本文深入介绍一下Android消息处理系统原理. Android系统中Looper负责管理线程的消息队列和消息循环,具体实现请参考Looper的源码. 可以通过Loop.myLooper(