java 如何知道此线程是否为 UI 线程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12855848/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 10:30:21  来源:igfitidea点击:

How to know if this thread is a UI Thread

javaandroidui-thread

提问by user1730789

Is there any way on Android to know, if the thread running my code, is the UI Thread or not ? In swing there was SwingUtilities.isEventDispatchThread()to tell me if i am on the UI Thread, or not. Is there any function in the Android SDK that lets me know this ?

Android 上有什么方法可以知道,如果线程运行我的代码,是否是 UI 线程?在 Swing 中有 SwingUtilities.isEventDispatchThread()告诉我我是否在 UI 线程上。Android SDK 中是否有任何功能让我知道这一点?

回答by Fenix Voltres

  1. Answer borrowed from here: How to check if current thread is not main thread

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

  2. Any Android app has only one UI thread, so you could somewhere in the Activity callback like onCreate() check and store its ID and later just compare that thread's ID to the stored one.

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

  3. Anyway, you can omit checking if you want to do something on the UI thread and have any reference to Activity by using

    mActivity.runOnUiThread( new Runnable() {
        @Override 
        public void run() {
        ...
        }
    });
    
  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() {
        ...
        }
    });
    

which is guaranteed to run on current thread, if it's UI, or queued in UI thread.

保证在当前线程上运行,如果它是 UI,或者在 UI 线程中排队。

回答by Cleosson

Yes, there is a way. Check the current thread object against main lopper's thread object. Main looper is always in the UI thread.

是的,有办法。根据主 lopper 的线程对象检查当前线程对象。主循环程序始终在 UI 线程中。

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

回答by Teovald

Hum actually due to Android architecture, all Activities run in the main thread, ie the UI thread. So when you are coding an activity, everything that is in your Activity is in the UI thread.
That is why in Honeycomb an error have been added when you are making network calls in the main thread : it totally blocks the UI.

嗯其实由于Android架构,所有的Activity都运行在主线程,即UI线程。因此,当您编写 Activity 时,Activity 中的所有内容都在 UI 线程中。
这就是为什么在 Honeycomb 中,当您在主线程中进行网络调用时会添加一个错误:它完全阻塞了 UI。

So by default you are in fact always working in the UI thread. Another thing : unless you explicitely ask it to be in another thread, a Service will operate on the same thread as the activities of its application.

因此,默认情况下,您实际上始终在 UI 线程中工作。另一件事:除非您明确要求它在另一个线程中,否则服务将在与其应用程序的活动相同的线程上运行。

So, what to do ?

那么该怎么办 ?

  • When you have to do heavy calculation in your activity; one solution is to use an AsyncTask (a class designed to allow you to easily use another thread). The code in onExecute() is run in another thread (but be cautious postExecute runs in your main thread). Another one is to manually start a new thread when AsyncTask is not really adapted.
  • If you create a service that does costly background tasks, make it run in another thread with the android:process=":my_process" attribute of the manifest. You will need to create an AIDL to communicate with this separated service, but it is not a complicated task.
  • Many objects, like for example the MediaPlayer, have Async variations of their methods. Try to to always use them.
  • 当您必须在活动中进行大量计算时;一种解决方案是使用 AsyncTask(一个旨在让您轻松使用另一个线程的类)。onExecute() 中的代码在另一个线程中运行(但要小心 postExecute 在您的主线程中运行)。另一种是在 AsyncTask 没有真正适配时手动启动一个新线程。
  • 如果您创建的服务执行代价高昂的后台任务,请使用清单的 android:process=":my_process" 属性使其在另一个线程中运行。您将需要创建一个 AIDL 来与这个分离的服务进行通信,但这并不是一项复杂的任务。
  • 许多对象,例如 MediaPlayer,都有其方法的异步变体。尝试始终使用它们。

回答by Tiago

Put a breakpoint where you want to check and, when it gets hit, check if you can interact with your UI (ie, if the UI is not frozen). If you can't interact with the UI then you are in the UI Thread, otherwise you are in a background thread.

在您想要检查的地方放置一个断点,当它被击中时,检查您是否可以与您的 UI 交互(即,如果 UI 没有被冻结)。如果您无法与 UI 交互,则您处于 UI 线程中,否则您处于后台线程中。