【问题标题】:Why use HandlerThread in Android为什么在 Android 中使用 HandlerThread
【发布时间】:2019-11-27 04:00:39
【问题描述】:

在 android 中,Handler 可用于发布/处理消息,如果我不使用 HandlerThread(将其 Looper 传递给 Handler),这是否意味着在这种情况下 Handler 使用 MainThread(UI Thread)的 Looper ?

如果 Handler 使用 MainThread 的 Looper 会得到什么结果?可能导致mainThread阻塞?

【问题讨论】:

    标签: android android-handler android-handlerthread


    【解决方案1】:

    如果您想一次执行一项后台任务,并且希望这些任务按执行顺序运行,则可以使用 HandlerThread。

    比如你要一个一个地做几个网络后台操作。

    是的,HandlerThread 有它自己的循环器,并且可以创建处理程序并发布它,(所以它不会阻塞主线程)。

    【讨论】:

      【解决方案2】:

      HandlerThread的正常使用方式如下:

      HandlerThread thread = new HandlerThread("A Handler Thread");
      thread.start();
      Handler handler = new Handler(thread.getLooper()){
          @Override
          public void handleMessage(Message msg) 
          {
          //....
          }
      };
      

      因为HandlerThread可以为Handler创建一个Looper,是一种方便的方式。

      当你创建一个新的 Handler 时,它会被绑定到创建它的线程的线程/消息队列——参见官方文档...

      【讨论】:

      • 这是官方文档。 Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called. 我节省了你的时间。
      【解决方案3】:

      如果我不使用 HandlerThread(将其 Looper 传递给 Handler),这是否意味着在这种情况下 Handler 使用 MainThread (UI Thread) 的 Looper?

      查看Handler的文档

      Handler ()
      

      默认构造函数将此处理程序与当前线程的 Looper 相关联。

      如果你当前的线程是 MainThread,它使用 MainThread(UI Thread) Looper。

      要将 Handler 显式关联到您的 MainThread(UI 线程),请编写以下代码。

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

      如果你写如下,它使用HandlerThread Looper。

      HandlerThread handlerThread = new HandlerThread("HandlerThread");
      handlerThread.start();
      Handler requestHandler = new Handler(handlerThread.getLooper());
      

      如果Runnable任务中有网络IO操作,则不能使用主线程looper。在这种情况下,HandlerThread 可以方便地发布 Runnable 执行网络 IO 操作的任务。

      你可以找到示例代码@How do I fix android.os.NetworkOnMainThreadException?

      如果 Handler 使用 MainThread 的 Looper 会得到什么结果?可能导致mainThread阻塞?

      如果您向 MainThread Looper 发送许多事件,它们将在 MainThread(UI 线程)本身上执行。如果提交的任务需要更多时间执行,则 MainThread 将被阻塞。

      查看下面的帖子了解Looper 的内部信息:

      What is the purpose of Looper and how to use it?

      【讨论】:

        【解决方案4】:

        正如Doc 所说:

        用于启动具有弯针的新线程的便捷类。
        然后可以使用 looper 来创建处理程序类。
        请注意,仍然必须调用 start()。

        HanderThread类继承自Thread类,它封装了Looper对象,这样我们就不用关心Looper打开和释放的细节了。与普通线程一样,我们需要使用Looper.prepare()Looper.loop() 将其转换为LooperThread

        【讨论】:

          【解决方案5】:

          似乎大家都解释了它的作用和使用方法,却忘了说明这个线程需要开发者使用后进行清理,否则会泄漏。使用后需要调用

          thread.quit()
          

          退出而不处理队列中的消息或

          thread.quitSafely();
          

          处理当前在队列中的消息。

          【讨论】:

            【解决方案6】:

            当你想要执行大量后台任务时,HandlerThread 很有用,因为它有自己的 looper。通常,如果您向 Handler 发布消息,它会使用 MainThread 的 looper。这意味着任务在 UI 线程上执行。但是在 HandlerThread 的情况下,这些任务是在工作线程上执行的。你可以找到更详细的解释here

            【讨论】:

              猜你喜欢
              • 2015-07-29
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-12-16
              • 2023-03-17
              • 2017-11-14
              • 2019-06-29
              • 2023-01-10
              相关资源
              最近更新 更多