为了活动小家电-Android Thread和Handler(四)

52 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第22天,点击查看活动详情

为了活动小家电,接着上篇搞!

什么是Looper?

  • Looper是指不断弹出待Handler处理的任务的结构。即MesseageQueue中的消息和runnables以先进先出的方式不断地被一个一个地检索。

  • 顾名思义,Looper 负责迭代。

  • Looper 与 Handler 通信最多。

    大多数与消息循环的交互都是通过Handler类进行的。

  • Looper的迭代工作是通过loop()函数的无限循环来完成的,与线程类型无关(不管是主线程还是通用线程)。 loop() 函数由一个无限循环组成,该循环重复直到弹出的内容为空。在这个无限循环中,msg.target.dispatchMessage(msg); 通过,Handler,target,处理任务。这里的 dispatch 是指将就绪状态变为运行状态的任务。

/**
 * 在这个线程中运行消息队列。 一定要call
 * {@link #quit()} 结束循环。
 */ 
public static void loop() {
        final Looper me = myLooper(); 
        final MessageQueue queue = me.mQueue;
        // 开始无限循环
        for (;;) { 
            Message msg = queue.next(); // might block
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }

            try {
                msg.target.dispatchMessage(msg);
                if (observer != null) {
                    observer.messageDispatched(token, msg);
                }
                dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
            } catch (Exception exception) {
                if (observer != null) {
                    observer.dispatchingThrewException(token, msg, exception);
                }
                throw exception;
            } finally {
                ThreadLocalWorkSource.restore(origWorkSource);
                if (traceTag != 0) {
                    Trace.traceEnd(traceTag);
                }
            }

            msg.recycleUnchecked();
        } 
    }

Looper 是如何创建的?

默认情况下,无论线程如何,每个 Looper 都存储在创建它的线程的线程本地存储 (TLS)中。MainLooper 主线程的looper ,在API 30之前,MainLooper是通过在ActivityThread.java的main函数中调用prepareMainLooper()来创建*的,而MainLooper是通过调用loop()来操作的。

// ActivityThread.java

public static void main(String[] args) {
  Looper.prepareMainLooper();
  Looper.loop();
} 

但是,在 API 30 之后,prepareMainLooper() 已被弃用,因为它已更改为在 Android 环境中直接创建 MainLooper 的方法 。因此,开发人员不会(像最初那样)参与 MainLooper 的创建,他们只需要通过getMainLooper()导入它。

另一方面,一般的线程默认是没有Looper的,所以要使用每个线程的Handler,就必须自己创建一个Looper。默认情况下,线程没有与之关联的消息循环。再加上普通线程没有 Looper 的原因,Looper 是 Android 引入的一种结构,但是Android 普通线程默认没有 Looper,因为它使用的是 Java 线程。

创建常规线程的 Looper 的方法是使用 prepare() 函数。此外,与主线程一样,它通过 loop() 调用工作。综上所述,开发者在使用通用线程的地方通过prepare()调用创建Looper,并通过loop()调用使Looper运行**。

// Android Developers : Looper   
class LooperThread extends Thread {
      public Handler mHandler;

      public void run() {
          Looper.prepare();

          mHandler = new Handler(Looper.myLooper()) {
              public void handleMessage(Message msg) {
                  // 在此处理传入的消息
              }
          };

          Looper.loop();
      }
  }

为了活动小家电,下篇接着搞!