理解UI线程

7 浏览
0 Comments

理解UI线程

例如,有许多任务被发布到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线程中,UI线程会发生什么? 如果Looper中没有任务,它是否会被暂停?

先感谢您。

admin 更改状态以发布 2023年5月22日
0
0 Comments

有关于该情况的许多答案。我将尝试准确地回答这些问题。

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

没有中断。Handler 将在指定时间(除非托管进程被杀死)在 MessageQueue 上发布 Message

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

Handler 的角度来看:它不知道应用程序是在前台还是后台。它只知道它应该稍后发布一条 Message

当后台没有任何任务发布到 UI 线程时,UI 线程会暂停吗?或者?所有发布到 UI 线程的任务都会暂停吗?

当活动完全加载后,如果没有任何任务发布到 UI 线程,UI 线程会发生什么情况?如果 Looper 中没有任何任务,则会暂停吗?

UI 线程在任何情况下都不会被“暂停”(除非托管进程被杀死)。只是由于 MessageQueue 为空,它会处于空闲状态,因此不需要执行任何作业。

顺便说一句,在应用程序进入后台时,避免执行与 UI 相关的操作,因为视图层次结构的状态不会正确保存。假设您在应用程序处于后台时进行了 textView.setText("bob") 操作。现在,这个 TextView 的状态不会被保存,因为 onSaveInstanceState() 已经被执行,并且不会再次执行。因此,如果应用程序的进程被杀死并重新创建,那么活动将以在调用 onSaveInstanceState() 时所拥有的状态进行恢复。现在用户看不到”bob”。

您可以使用 Handler#removeCallbacks() API 取消计划的事件。

0
0 Comments

首先让我们先来学习一些术语。

Handler

Handler允许从其他后台线程与UI线程进行通信。在Android中这非常有用,因为Android不允许其他线程直接与UI线程进行通信。技术上来说,这是一种将消息或可运行对象发布到与其关联的线程消息队列的方法。

因此,Handler执行了两个任务:

  • 计划消息和可运行对象在未来某个时刻执行;
  • 将动作排入与您自己不同的另一个线程的队列中。

那么如何安排呢?

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:线程和Looper以及Handler一直运行,直到用户终止或系统杀死它们。

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

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

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

0