Android 官网对Looper对象的说明:

public class Looper                
extends Object
  

Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, callprepare() in the thread that is to run the loop, and thenloop() to have it process messages until the loop is stopped.

Most interaction with a message loop is through the Handler class.

在消息处理机制中,消息都是存放在一个消息队列中去,而应用程序的主线程就是围绕这个消息队列进入一个无限循环的,直到应用程序退出。如果队列中有消息,应用程序的主线程就会把它取出来,并分发给相应的Handler进行处理;如果队列中没有消息,应用程序的主线程就会进入空闲等待状态,等待下一个消息的到来。在Android应用程序中,这个消息循环过程是由Looper类来实现的,它定义在frameworks/base/core/java/android/os/Looper.java文件中。

先理解几个概念:

Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理。

Handler:处理者,负责Message的发送及处理。使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等。

MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。当然,存放Message并非实际意义的保存,而是将Message以链表的方式串联起来的,等待Looper的抽取。

Looper:消息泵,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue需要一个Looper

Thread:线程,负责调度整个消息循环,即消息循环的执行场所。

Android 中的 Looper 对象_第1张图片

参考:Android Looper和Handler

This is a typical example of the implementation of a Looper thread, using the separation ofprepare() andloop() to create an initial Handler to communicate with the Looper.

  class LooperThread extends Thread {      public Handler mHandler;            public void run() {          Looper.prepare();                    mHandler = new Handler() {              public void handleMessage(Message msg) {                  // process incoming messages here              }          };                    Looper.loop();      }  }

在run()方法中做了两件事情,一是创建了一个Handler实例,二是通过Looper类使该线程进入消息循环中。

主要方法简介:

static void loop(): Run the message queue in this thread.

static voidprepare(): Initialize the current thread as a looper.若不调用,则异常:Can‘t create handler inside thread that has not called Looper.prepare()。

Handler处理消息总是在创建Handler的线程里运行。而我们的消息处理中,不乏更新UI的操作,不正确的线程直接更新UI将引发异常。因此,需要时刻关心Handler在哪个线程里创建的。

如何更新UI才能不出异常呢?SDK告诉我们,有以下4种方式可以从其它线程访问UI线程:

·Activity.runOnUiThread(Runnable)

·View.post(Runnable)

·View.postDelayed(Runnable, long)

·Handler

其中重点说一下的是View.post(Runnable)方法。在post(Runnable action)方法里View获得当前线程UI线程Handler然后将action对象postHandler里。在Handler里,它将传递过来的action对象包装成一个MessageMessagecallbackaction),然后将其投入UI线程的消息循环中。在Handler再次处理该Message时,有一条分支(未解释的那条)就是为它所设,直接调用runnablerun方法。而此时,已经路由到UI线程里,因此,我们可以毫无顾虑的来更新UI

几点小结:

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

·一个Looper对应一个MessageQueue

·一个线程对应一个Looper

·一个Looper可以对应多个Handler

·不确定当前线程时,更新UI时尽量调用post方法

1.主线程:

Handler mainThreadHandler = new Handler(Looper.getMainLooper());

mainThreadHandler.post(runnable);

2.非主线程:

HandlerThread thread = new HandlerThread("Default Thread", Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
Handler defThreadHandler = new Handler(thread.getLooper());

defThreadHandler.post(runnable);

defThreadHandler.removeCallbacks(runnable);//Remove any pending posts of Runnable r that are in the message queue.

3.线程池:

ExecutorServicecachedThreadPool = Executors.newCachedThreadPool();

cachedThreadPool.execute(runnable);

更多相关文章

  1. 线程池的封装和使用(二)
  2. Android studio 简单的多线程
  3. Android 为线程增加Looper
  4. Android中对后台任务线程性能的说明及优化
  5. Android 线程池管理工具类
  6. android:Handler开启线程定时循环
  7. Android 后台线程调用前台线程的几种方法
  8. Android 创建线程执行任务
  9. android 线程之创建一个子线程,并在UI线程中进行交互

随机推荐

  1. docker 学习第一节课
  2. python之类的继承
  3. python之类的多态
  4. 找到适合您的数字化转型策略的3个步骤
  5. python之类(class)的笔记
  6. 嵌套函数和作用域和匿名函数
  7. 生成器的妙用
  8. 深圳高新技术企业补贴及认定标准
  9. Centos7系统安装nextcloud13.0.6,开始遇
  10. 三级菜单和购物车