我要做 Android 之消息机制

正如我们所知,在android中如果主线程中进行耗时操作会引发ANR(Application Not Responding)异常。

造成ANR的原因一般有两种:

  1. 当前的事件没有机会得到处理(即主线程正在处理前一个事件,没有及时的完成或者looper被某种原因阻塞住了)
  2. 当前的事件正在处理,但没有及时完成

为了避免ANR异常,android使用了Handler消息处理机制。让耗时操作在子线程运行。

因此产生了一个问题,主线程中的Looper.loop()一直无限循环检测消息队列中是否有新消息为什么不会造成ANR?

 while (true) {       //取出消息队列的消息,可能会阻塞       Message msg = queue.next(); // might block       ...       //解析消息,分发消息       msg.target.dispatchMessage(msg);       ...    }

显而易见的,如果main方法中没有looper进行循环,那么主线程一运行完毕就会退出。

总结:ActivityThread的main方法主要就是做消息循环,一旦退出消息循环,那么你的应用也就退出了。

因为Android 的是由事件驱动的,looper.loop() 不断地接收事件、处理事件,每一个点击触摸或者说Activity的生命周期都是运行在 Looper.loop() 的控制之下,如果它停止了,应用也就停止了。只能是某一个消息或者说对消息的处理阻塞了 Looper.loop(),而不是 Looper.loop() 阻塞它。

也就说我们的代码其实就是在这个循环里面去执行的,当然不会阻塞了。

如果某个消息处理时间过长,比如你在onCreate(),onResume()里面处理耗时操作,那么下一次的消息比如用户的点击事件不能处理了,整个循环就会产生卡顿,时间一长就成了ANR。

而且主线程Looper从消息队列读取消息,当读完所有消息时,主线程阻塞。子线程往消息队列发送消息,并且往管道文件写数据,主线程即被唤醒,从管道文件读取数据,主线程被唤醒只是为了读取消息,当消息读取完毕,再次睡眠。因此loop的循环并不会对CPU性能有过多的消耗。

总结:Looer.loop()方法可能会引起主线程的阻塞,但只要它的消息循环没有被阻塞,能一直处理事件就不会产生ANR异常。


 

更多相关文章

  1. Android 的消息机制之 Handler
  2. 【Android】Android事件分发机制的学习笔记和理解
  3. Handler消息传送机制总结
  4. 调用Android自带日历功能(日历列表单、添加一个日历事件)
  5. [原]Android应用程序线程消息循环模型分析
  6. Android中消息系统模型和Handler Looper
  7. Android 事件处理(―)(附源码)

随机推荐

  1. Android(安卓)Wifi Hotspot Manager Clas
  2. [转]Android(安卓)源代码结构
  3. Android7.0中文文档(API)-- AlphabetIndexe
  4. Android(安卓)源代码结构
  5. Android(安卓)Init Language(android init
  6. 制作android/cordova splash screen
  7. Android(安卓)EditText 限制文本框输入的
  8. Android图片的处理类
  9. Android7.0中文文档(API)-- Filter
  10. gradle DSL method not found: android()