首先看图

应用启动时的入口是ActivityThread的main函数,即是Java的启动入口main函数。在这个main函数中会创建主线程的Looper,之后在主线程中创建的Handler使用的消息机制都执行于main函数的Looper中,其实其他代码也都是执行在loop中的。Looper.loop()有一个for的死循环不断读取消息进行处理,而mMainLooper是不能调用Looper.quit()或Looper.quitSafely()函数的,所以mMainLooper会不停的读取消息链表的消息然后处理,如果有某种消息处理时间过长就会导致卡顿、ANR等。

消息传递流程

首先是创建Handler,而Handler主要的方法就是sendMessage,它用于将消息保存入队列,等待loop中读取再执行。

消息的实体是Message,它有一个next属性,这是组成链表的结构,属性when表示消息执行时间,由参数delayMillis决定,但因为Handler可以在多线程中执行,所以为了保证多线程执行的唯一性,使用了synchronized进行加锁处理,保证在消息入队列和消息出队列时的唯一性,when只保证了消息的执行顺序,不保证执行时间。

Message.target的类型是Handler,这也是保证消息处理后能原路返回结果,但是这个的存在同时也存在内存泄漏的风险。内存泄漏是因为内部类保持了外部类的引用,导致外部类无法释放。那么使用Handler的时候就需要注意这个了,首先需要清空Message才能释放掉Handler,从而再释放Activity等。也有的解决方法是创建特殊的Handler。

将消息保存到队列是MessageQueue的功能,但其实是Message的结构决定的,根据参数when决定消息压入队列链表的某个位置。

Looper.loop死循环遍历消息队列,假如队列是空queue.next()会进行休眠等待,直到下个消息的到来。

主线程的Looper是不能quit的,但是子线程的Looper是可以quit的,也为了节省资源,可以看到它会调用MessageQueue的quit方法将消息队列清空并唤醒Looper,让Looper.loop的死循环的queue.next()返回一个null,从而结束死循环,这样才算是完全释放这个Looper,否则Looper会一直休眠等待。

更多相关文章

  1. C语言函数的递归(上)
  2. Surfaceflinger 一点解释
  3. Android(安卓)Studio 中利用 Android(安卓)Profiler 测量应用性
  4. 阿里ctf-2014 android 第一、二题
  5. handler机制简析
  6. 《深入理解Android(安卓)卷1》读书笔记 (二)—— Android(安卓)zyg
  7. Android(安卓)电源管理 (部分转载)
  8. Wifi 资源整理
  9. Android(安卓)NDK C++中的多线程

随机推荐

  1. 面向Android微博客户端"Crowdroid2.5.0"
  2. 主题背景色
  3. Android(安卓)Studio 报Error:(29, 17) F
  4. Android(安卓)Sensor Framework(狠详)
  5. android 自定义log打印
  6. 在Android上使用微信开源数据库框架WCDB
  7. 安卓apk签名
  8. 【Android(安卓)Developers Training】 1
  9. CTS运行注意事项(不断更新中...)
  10. ejoy2d源代码阅读之一(启动流程)