了解 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);

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

即使在后台也会处理这些任务吗?整个 UI 线程是否会在后台挂起?或?发布到 UI 线程的所有任务都已挂起?

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

提前谢谢。

让我们先用几个术语弄脏。

处理器:

处理程序允许从其他线程与 UI 线程通信 后台线程。这在安卓中很有用,因为安卓不允许 其他线程直接与 UI 线程通信。 用技术术语来说,这是一种发布消息或运行到关联线程消息队列的方法。

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

  • 将消息和可运行对象安排为将来某个时间点执行;以及
  • 将要在与您自己的线程不同的线程上执行的操作排队。

那么如何安排一个

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

卢珀:

无论我之前提到的是什么,都由 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 和处理程序)继续运行,直到它被用户完成或被系统杀死。

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

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

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

关于这个案子有很多答案。我将尝试准确回答这些问题。

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

没有任何东西被打断。Handler将在指定时间发布MessageMessageQueue(除非托管进程被终止)。

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

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

整个 UI 线程是否会在后台挂起?或?发布到 UI 线程的所有任务都已挂起?

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

在任何情况下,UI 线程都不会"挂起">(除非托管进程被终止)。只是由于MessageQueue是空的,它会闲置——因此不需要做任何工作。

作为旁注,当应用进入后台时,请不要执行与 UI 相关的操作,因为视图层次结构的状态将无法正确保存。假设当应用程序处于后台时,您一次执行了textView.setText("bob")。现在,不会保存此TextView的状态,因为onSaveInstanceState()已经执行并且不会再次执行,因此,如果应用程序的进程被终止并重新创建(即由于系统资源不足),则活动将以调用onSaveInstanceState()时的状态恢复。现在用户不会看到"鲍勃"。

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

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

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

让我们从 Looper 概念开始。这对于了解 UI 线程的工作方式非常重要。Looper 是一种在给定线程中循环并处理传入消息的东西,当没有任务时,它会循环并等待新任务,因此,回答您的最后一个问题,线程不会被挂起。Looper 旨在即使在没有任务的情况下也能保持线程的活动状态。默认情况下,Android 中的 UI 线程有自己的 Looper。

当安卓应用程序进入后台时,这些任务会发生什么? 这些任务即使在后台也会处理吗?整个 UI 线程是否会在后台挂起?或?发布到 UI 线程的所有任务都已挂起?

进入后台不会更改主线程的任何内容。它一直运行,直到应用程序被终止。因此,在处理程序上计划的代码将只运行。

附带说明一下。这里可能的问题是,当活动在后台时,它可能会被系统杀死,并且您尝试更改它的 UI 会使应用程序崩溃(有一些类似的情况),但它与 UI 线程并不真正相关。

总而言之,UI 线程在任何情况下都不会被框架挂起。它只是运行并处理您提供给它的所有内容,或者等到赋予它新任务。

在这里,您可以在官方文档中找到主线程的描述。

这是一个很好的关于活套的SO线程。

当安卓应用程序转到 背景?

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

最佳解决方案:当应用处于后台时更新处理程序中的任何视图

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

这些任务即使在后台也会处理吗?将 完整的 UI 线程在后台挂起?或?所有任务 发布到 UI 线程被暂停?

正如我上面提到的,此任务将按原样工作。

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

之后没有发布任何任务时,UI 线程会发生什么情况 活动已完全加载?如果有的话,是否会暂停 没有任务在 Looper 中?

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

UI 线程不会自行挂起,直到并且除非您编写一些代码来:)更改它。

很高兴阅读:Androids Handler.post,到底发生了什么

Android 中的 Looper、Handler 和 MessageQueue 之间有什么关系?

相关内容

  • 没有找到相关文章

最新更新