理解基本概念

  • Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理。
  • Handler:处理者,负责Message的发送及处理。使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等。
  • MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。当然,存放Message并非实际意义的保存,而是将Message以链表的方式串联起来的,等待Looper的抽取。
  • Looper:消息泵,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue需要一个Looper。
  • Thread:线程,负责调度整个消息循环,即消息循环的执行场所。

下面的图用来说明Handler, Looper, MessageQueue的关系:

Handler,Looper和MessageQueue就是简单的三角关系。Looper和MessageQueue一一对应,创建一个Looper的同时,会创建一个MessageQueue。而Handler与它们的关系,只是简单的聚集关系,即Handler里会引用当前线程里的特定Looper和MessageQueue。这样说来,多个Handler都可以共享同一Looper和MessageQueue了。当然,这些Handler也就运行在同一个线程里。

Whenever you first start an Android application, a thread called "main" is automatically created. The main thread, also called the UI thread, is very important because it is in charge of dispatching the events to the appropriate widgets and this includes the drawing events. It is also the thread you interact with Android widgets on. For instance, if you touch the a button on screen, the UI thread dispatches the touch event to the widget which in turn sets its pressed state and posts an invalidate request to the event queue. The UI thread dequeues the request and notifies the widget to redraw itself.

This single thread model can yield poor performance in Android applications that do not consider the implications. Since everything happens on a single thread performing long operations, like network access or database queries, on this thread will block the whole user interface. No event can be dispatched, including drawing events, while the long operation is underway. From the user's perspective, the application appears hung. Even worse, if the UI thread is blocked for more than a few seconds (about 5 seconds currently) the user is presented with the infamous "application not responding" (ANR) dialog.

看了这段话,就可以理解为什么有的文章里总是提到Android的单线程模型了。

Now that you know you must avoid lengthy operations on the UI thread, you will probably use extra threads (background or worker threads) to perform these operations, and rightly so. Let's take the example of a click listener downloading an image over the network and displaying it in an ImageView:

public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
Bitmap b = loadImageFromNetwork();
mImageView.setImageBitmap(b);
}
}).start();
}

At first, this code seems to be a good solution to your problem, as it does not block the UI thread. Unfortunately, it violates the single thread model: the Android UI toolkit is not thread-safe and must always be manipulated on the UI thread. In this piece of code, the ImageView is manipulated on a worker thread, which can cause really weird problems. Tracking down and fixing such bugs can be difficult and time-consuming.

这里最重要的一句话就是Android UI 控件(toolkit)不是线程安全的,对它们的操作必须在UI线程里完成。

Android offers several ways to access the UI thread from other threads. You may already be familiar with some of them but here is a comprehensive list:

  • Activity.runOnUiThread(Runnable)
  • View.post(Runnable)
  • View.postDelayed(Runnable, long)
  • Handler


Reference:

1. http://www.cnblogs.com/xirihanlin/archive/2011/04/11/2012746.html

2.

更多相关文章

  1. SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
  2. android vold架构详解(3)_两个Socket
  3. EventBus的简单用法及介绍
  4. thread in android ndk
  5. Android(安卓)EventBus的使用
  6. 谈谈Binder
  7. Android(安卓)thumbnail 缩略图的获取及与原始图片的映射关系
  8. interview-question
  9. 2018年Android面试题汇总四(持续更新中)

随机推荐

  1. Android完整的Activity页面
  2. Android(安卓)read system font
  3. Android的手机震动
  4. [转]使HOME键有效
  5. Android(安卓)Wi-Fi工作原理
  6. android 9.0默认launcher
  7. Android—Android中监听EditText文本输入
  8. Android属性gravity与layout_gravity的区
  9. Android联系人数据库全
  10. DataBing