6

我不得不将 Looper 添加到以下代码中:

public class MyRunnable implements Runnable
{
  @Override
  public void run()
  {
      Looper.prepare();
      final Looper looper = Looper.myLooper();

      new Handler().postDelayed(
          new Runnable()
          {
            @Override
            public void run()
            {
              try
              {
              }
              catch (Exception ex)
              {
              }
              finally
              {
                looper.quit();
              }
            }
          }, 100);

      Looper.loop();
  }
}

请注意,我在可运行文件中有一个可运行文件。嵌套的 runnable 通过 Handler 执行。最初我没有 Looper,但 Android 抱怨说我需要在执行另一个线程之前调用 Looper.prepare。

我阅读了 Looper,但它似乎仍然有点神秘。它似乎就像某种内部消息传递管道。我不清楚为什么这是必要的,因为没有消息从我的外部运行到我的内部运行。尽管这是真的,但似乎 Android 只是制定了一个硬性规则,即如果你从一个线程调用一个线程,你也必须调用 Looper.prepare。即使我按原样接受,它仍然无助于理解为什么我需要调用 looper.loop 和 looper.quit。如果我省略 Looper.loop,我的 Handler 永远不会运行,这是不清楚的。Looper.loop 做了什么让我的 Handler 运行?

4

3 回答 3

8

这是一篇很棒的文章。

Android 中的 Looper 和 Handler

它带有一个简单的模式,可以直接理解LoopersHandler之间的关系。

在这个模式中,我们看到,在同一个线程中(由大矩形描绘),无论您创建多少个处理程序,它们都将使用相同的 Looper,即该线程的唯一 Looper。

处理程序和循环器

注意

Looper 必须准备好允许关联的处理程序处理发布的消息

Android 应用程序,更准确地说是 android 应用程序 UI 线程(主线程),已经带有一个准备好的 Looper(mainLooper)。

这是与 UI 线程通信的方法。

于 2014-06-18T07:49:22.017 回答
4

一个简单的looper概念:

  1. 您创建和运行的每个工作线程都会在执行最后一次操作后结束。

  2. 为了防止您的线程终止,您可以通过调用来启动循环Looper.loop(),将其视为while(true){}语句。在调用之前,如果尚未准备Looper.loop()好,您必须使用 准备循环。Looper.prepare()要终止循环并结束线程,您需要调用looper.quit()looper。

现在对于您从 Android 收到的通知:

当您在线程中创建 Handler 时,它将绑定到创建它的线程,并且当您使用此 Handler 发布可运行文件时,代码将在 Handler 的线程上运行。

因此,当系统看到您想要在绑定到线程的 Handler 上运行一些代码(尤其是未来 100 毫秒)时,一旦它完成调用它建议用来Looper.loop()阻止该线程的 post 方法,该线程就会死掉终止,从而使您能够在仍然存在的线程中正确运行第二个 Runnable。

于 2016-02-22T12:03:34.480 回答
1

我发现以下教程对理解 looper 的概念非常有帮助。
Looper 和处理程序简介

于 2013-07-05T08:03:04.917 回答