如何判断一个线程是否为UI线程

22

在Android中有没有一种方法可以知道运行我的代码的线程是否是UI线程?在swing中有SwingUtilities.isEventDispatchThread()可以告诉我当前是否处于UI线程中,那么在Android SDK中有没有类似的函数呢?


1
为什么需要知道代码运行在哪个线程上?如果代码是用于UI线程的,那就简单地将其分派到那里。 - Nikolay Elenkov
通常你会知道一个方法是否在UI线程上执行。有没有特别的情况让你感到疑惑? - njzk2
只是确保我的多线程代码的一种方式。 - user1730789
可能是重复的问题:如何检查当前线程是否不是主线程 - blahdiblah
4个回答

40
  1. 从这里借鉴的答案:如何检查当前线程不是主线程

    Looper.myLooper() == Looper.getMainLooper()

  2. 任何Android应用程序只有一个UI线程,因此你可以在Activity回调函数(例如onCreate())中检查并存储其ID,并将该线程的ID与存储的ID进行比较。

    mMainThreadId = Thread.currentThread().getId();

  3. 无论如何,如果您想要在UI线程上执行某些操作并具有对Activity的任何引用,则可以省略检查,使用:

    mActivity.runOnUiThread( new Runnable() {
        @Override 
        public void run() {
        ...
        }
    });
    
    这将保证代码在当前线程中运行,如果是UI线程,则直接在UI线程中运行;否则将排队等待在UI线程中执行。

8

是的,有一种方法。 将当前的线程对象与主looper的线程对象进行比较。主looper始终在UI线程中。

boolean isOnUiThread = Thread.currentThread() == Looper.getMainLooper().getThread();

0

由于 Android 架构的原因,所有活动都在主线程中运行,即 UI 线程。因此,当您编写一个活动时,您的 Activity 中的所有内容都在 UI 线程中。

这就是为什么在 Honeycomb 中,当您在主线程中进行网络调用时会出现错误:它会完全阻塞 UI。

因此,默认情况下,您实际上总是在 UI 线程中工作。

另一件事:除非您明确要求在另一个线程中运行,否则服务将在其应用程序的活动所在的同一线程上运行。

那么,该怎么办呢?

  • 当您需要在活动中进行大量计算时,一种解决方案是使用 AsyncTask(一个专门设计用于轻松使用另一个线程的类)。onExecute() 中的代码在另一个线程中运行(但要小心 postExecute 在您的主线程中运行)。另一种方法是在 AsyncTask 不太适合时手动启动新线程。
  • 如果您创建了一个执行昂贵后台任务的服务,请使用清单文件中的 android:process=":my_process" 属性使其在另一个线程中运行。您需要创建一个 AIDL 与这个分离的服务通信,但这不是一个复杂的任务。
  • 许多对象,例如 MediaPlayer,都有其方法的异步变体。尽量始终使用它们。

-1

在想要检查的地方设置断点,当它被触发时,检查是否可以与您的UI交互(即,如果UI没有冻结)。如果无法与UI交互,则表示您在UI线程中,否则您在后台线程中。


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