了解UI线程

时间:2018-03-03 05:59:07

标签: java android android-handler ui-thread android-looper

例如,有许多任务发布到UI线程,如下所示。

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

handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        // Some logic to display/update something in UI
    }
}, 5000);

当android应用程序进入后台时,这些任务会发生什么?

即使在后台也会处理这些任务吗?完整的UI线程是否会在后台暂停?要么?发布到UI线程的所有任务都被暂停?

在活动完全加载后没有任务发布到UI线程时会发生什么?如果Looper中没有任务,它会被暂停吗?

提前致谢。

4 个答案:

答案 0 :(得分:3)

首先让一些条款变得肮脏。

Handler

  

Handler允许与其他人的UI线程进行通信   背景线程。这在Android中很有用,因为android不允许   其他线程直接与UI线程通信。   在技​​术方面,它是一种将Messages或runnable发布到关联的线程消息队列的方法。

所以总共有两个任务由处理程序

执行
  • 安排消息和runnables作为未来的某个点执行;和
  • 将要在不同于自己的线程上执行的操作排入队列。

所以如何安排一个

post(Runnable),
postAtTime(Runnable, long),
postDelayed(Runnable, Object, long),
sendEmptyMessage(int),
sendMessage(Message), 
sendMessageAtTime(Message, long),
sendMessageDelayed(Message, long).

Looper:

  

我之前提到的任何内容都得到了Looper的支持它有一个loop()   保持运行和侦听新消息的方法,主线程有一个一直在运行,所以你可以从另一个线程接收消息到这个线程,如果你正在创建自己的线程,想要听,那么别忘了在运行循环的线程中调用prepare()。

一个简单的例子

     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();
      }
  }

现在回答你的问题:

1:Things(线程等Looper和Handler)继续运行,直到用户完成或被系统杀死。

2:looper有一个loop()方法,它将处理队列中的每条消息,并在队列为空时阻塞。

3:如果从后台线程更新UI,请确保app位于前台或终止onDestroy()中的后台线程,您可以使用handler.getLooper().quitSafely()handler.looper.quit()退出looper处理消息处理程序附加到主线程。

建议在方向更改或其他配置更改时确保终止后台线程。

答案 1 :(得分:2)

UI线程也称为主线程,它是默认情况下在您打开应用程序时启动的线程,并且除非您将它们卸载到其他线程,否则所有交互都会发生。它不依赖于应用程序的可见性,只要应用程序存在,它就会运行。它没有被系统暂停。

  

在活动完全加载后没有任务发布到UI线程时会发生什么?如果Looper中没有任务,它会被暂停吗?

让我们从Looper概念开始。了解UI线程的工作方式非常重要。 Looper是一个在给定线程中循环并处理传入消息的东西,当没有任务循环并等待新任务时,所以,回答你的上一个问题,线程不会被暂停。 Looper旨在使线程保持活动,即使没有任务。 Android中的UI线程默认拥有自己的Looper。

  

当android应用程序进入后台时,这些任务会发生什么?   这些任务是否会在后台处理?完整的UI线程是否会在后台暂停?要么?发布到UI线程的所有任务都被暂停了?

转到后台不会改变主线程的任何内容。它一直在运行,直到应用程序被杀死。因此,在处理程序上安排的代码将运行。

旁注。这里可能存在的问题是,虽然活动在后台,但它可以被系统杀死而你试图改变它的UI会使应用程序崩溃(有一些类似的场景),但它与UI线程并没有真正关系。

总而言之,在任何条件下,框架都不会暂停UI线程。它只是运行并处理你提供的所有内容,或等待直到给它新的任务。

Here你可以在官方文档中找到主线程的描述。

This是关于looper的好SO线程。

答案 2 :(得分:2)

  

当android应用程序进入时,这些任务会发生什么   背景

它将按预期工作,UI更改的行为没有变化。唯一的问题是我们无法看到这些变化。

最佳解决方案: 当app在后台时,更新处理程序中的任何视图

例如: TextView 并在其中设置一些文本,并在应用程序进入前台后获取此TextView值。

  

即使在后台也会处理这些任务吗?请问   完整的UI线程在后台暂停?要么?所有的任务   发布到UI线程被暂停?

正如我上面提到的,这项任务将按原样运作。

当您移动到后台时,应用程序不会更改UI线程,它将保持原样。

  

如果之后没有任何任务发布到UI线程会发生什么   活动完全加载?如果有的话会被暂停吗?   Looper中没有任务?

简单地说,有Looper线程,例如UI线程。这样的线程有自己的Looper,它为线程运行一个消息循环。消息队列完成后,它将自行完成。

UI线程不会不惜任何代价自行暂停,除非你写一些代码来改变它:)。

很高兴阅读: Androids Handler.post, what happens exactly

What is the relationship between Looper, Handler and MessageQueue in Android?

答案 3 :(得分:2)

关于此案有很多答案。我会尽力回答问题。

  

当android应用程序转到后台时,这些任务会发生什么?

没有任何事情被打断。 Handler会在指定时间内Message发布MessageQueue(除非主机进程被终止)。

  

即使在后台也会处理这些任务吗?

Handler的角度来看:它不知道应用是在前台还是在后台。它只知道它应该在一段时间之后发布Message

  

完整的UI线程是否会在后台暂停?要么?发布到UI线程的所有任务都被暂停了?

     

在活动完全加载后没有任务发布到UI线程时会发生什么?如果Looper中没有任务,它会被暂停吗?

在任何情况下,UI线程都不会被"暂停" (除非托管进程被终止)。它只是由于MessageQueue为空而无法空闲 - 因此无需完成任务。

作为旁注,当应用程序转到后台时,请不要执行与UI相关的操作,因为视图层次结构状态不会被正确保存。假设您在app处于后台时一次执行textView.setText("bob")。现在,这个TextView的状态不会被保存,因为onSaveInstanceState()已经执行并且不会被再次执行,因此如果应用程序的进程被终止并重新创建(即,由于系统资源短缺,那么活动将在调用onSaveInstanceState()时具有其拥有的状态。现在用户不会看到" bob"

您可以使用Handler#removeCallbacks() API取消预定的活动。