如何在Android上检测UI线程?

123

有没有一种可靠的方法来检测在应用程序中 Thread.currentThread() 是否为 Android 系统 UI 线程?
我想在我的模型代码中加入一些断言,以确保只有一个线程(例如 UI 线程)访问我的状态,以确保不需要任何类型的同步。


请查看我的答案:https://dev59.com/smgu5IYBdhLWcg3wUljt#41280460 - android developer
7个回答

209

通常确定UI线程的标识的常见做法是使用 Looper#getMainLooper:

if (Looper.getMainLooper().getThread() == Thread.currentThread()) {
  // On UI thread.
} else {
  // Not on UI thread.
}

从API级别23及以上,有一种稍微更易读的方法,可以使用主循环器上的新帮助程序方法isCurrentThread

if (Looper.getMainLooper().isCurrentThread()) {
  // On UI thread.
} else {
  // Not on UI thread.
}

6
这个答案也不错) - UnknownJoe

44

我认为最好的方法是这样的:

 if (Looper.getMainLooper().equals(Looper.myLooper())) {
     // UI thread
 } else {
     // Non UI thread
 }

3
不需要使用equals,因为我们只比较引用,并且此外它们都是静态的。 - mr5

9
从API级别23开始,Looper有一个很好的辅助方法isCurrentThread。您可以获取mainLooper并通过以下方式查看它是否为当前线程:
Looper.getMainLooper().isCurrentThread()

这与以下内容基本相同:

Looper.getMainLooper().getThread() == Thread.currentThread()

但它可能会更易读且更容易记忆。


7
public boolean onUIThread() {
    return <a rel="nofollow noreferrer" href="https://developer.android.com/reference/android/os/Looper.html">Looper</a>.<a rel="nofollow noreferrer" href="https://developer.android.com/reference/android/os/Looper.html#getMainLooper()">getMainLooper()</a>.<a rel="nofollow noreferrer" href="https://developer.android.com/reference/android/os/Looper.html#isCurrentThread()">isCurrentThread()</a>;

}

但是它需要API 23级。


很好知道! - Ahmed Alejo

2
除了检查looper之外,如果您曾尝试在onCreate()中注销线程ID,则会发现UI线程(主线程) ID始终等于1。因此,
if (Thread.currentThread().getId() == 1) {
    // UI thread
}
else {
    // other thread
}

我找不到任何官方文档证实这是真的,并且将始终如此。你有链接吗? - intrepidis
当我想要监视多线程行为时,这是我在logcat中发现的。您可以尝试输出线程ID。 - yushulx
8
我极力反对这样做,因为该值可能特定于您的设备和/或Android版本。即使现在在每个Android设备上都是这种情况,也不能保证它在后续版本中仍然是这样。在运行onCreate()时将线程ID保存在类成员中似乎更合理一些。 - personne3000

2

Kotlin的不错扩展:

val Thread.isMain get() = Looper.getMainLooper().thread == Thread.currentThread()

所以你只需要调用:

Thread.currentThread().isMain

0

4
我的应用程序可以运行,但是它有几个作者,变得越来越庞大和复杂。我想要做的是添加一个额外的安全保障,即一个断言,用于捕获如果有人从另一个线程调用仅设计为从 GUI 线程调用的方法时的错误。 - ParDroid
我目前正在修复一个bug,使用runOnUiThread会导致用户体验闪烁。 - fobbymaster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接