445

I need to check if the thread running a certain piece of code is the main (UI) thread or not. How can I achieve this?

Eiko
  • 25,483
  • 15
  • 55
  • 70
Charlie-Blake
  • 10,572
  • 13
  • 53
  • 90
  • example to demonstrate with thread example http://code2concept.blogspot.in/2015/02/androidhow-to-find-on-which-thread-code.html – Nitesh Tiwari Jun 29 '15 at 18:12

12 Answers12

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

if this returns true, then you're on the UI thread!

Carnal
  • 21,284
  • 6
  • 56
  • 73
136

you can use below code to know if current thread is UI/Main thread or not

if(Looper.myLooper() == Looper.getMainLooper()) {
   // Current Thread is Main Thread.
}

or you can also use this

if(Looper.getMainLooper().getThread() == Thread.currentThread()) {
   // Current Thread is Main Thread.
}

Here is similar question

Community
  • 1
  • 1
AAnkit
  • 26,788
  • 11
  • 57
  • 70
  • 10
    Should one consider the latter as the safer option as there is no guarantee that any arbitrary thread is associated with a Looper (assuming that the main thread is always associated with a looper)? – Janus Varmarken Jan 07 '16 at 16:58
  • `Looper.myLooper()` will return null if the thread is not associated with a Looper. So both are safe and have the same result but the first one is a little bit slower while it searches inside a map to find out the looper and its associated thread and do some other stuff . – Saeed Masoumi Nov 03 '18 at 08:26
71

The best way is the clearest, most robust way: *

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

Or, if the runtime platform is API level 23 (Marshmallow 6.0) or higher:

Looper.getMainLooper().isCurrentThread()

See the Looper API. Note that calling Looper.getMainLooper() involves synchronization (see the source). You might want to avoid the overhead by storing the return value and reusing it.

   * credit greg7gkb and 2cupsOfTech

Michael Allan
  • 3,431
  • 22
  • 28
  • What do you mean by "under API 23 or higher"? That doesn't make much sense to me..Also the exact same answer was posted by AAnkit, below.. – Mike Dec 02 '15 at 20:44
  • @Mike Thanks, I fixed the API bit. AAnkit actually favours `Looper.myLooper() == Looper.getMainLooper()`, which I think is less clear. I credit greg7gkb. – Michael Allan Dec 02 '15 at 21:00
  • 1
    should this be a comparison with == or equals() as Android Studio is raising a warning ? – 2cupsOfTech Jul 28 '17 at 14:19
  • @2cupsOfTech On 2nd thought, that’s good advice. Currently both tests are the same at runtime because [Thread](https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html) does not override `equals`, and so falls back to `==`, but that could change in future. So I corrected the answer. – Michael Allan Oct 09 '18 at 01:10
27

Summarizing the solutions, I think that's the best one:

boolean isUiThread = VERSION.SDK_INT >= VERSION_CODES.M 
    ? Looper.getMainLooper().isCurrentThread()
    : Thread.currentThread() == Looper.getMainLooper().getThread();

And, if you wish to run something on the UI thread, you can use this:

new Handler(Looper.getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
       //this runs on the UI thread
    }
});
copolii
  • 13,790
  • 10
  • 48
  • 78
android developer
  • 112,189
  • 137
  • 688
  • 1,196
  • Other answers around Handler recommend using ".postDelayed()" rather than ".post()". What is the main difference and can you mention why you recommended using ".post()"? – AJW Nov 10 '21 at 21:26
  • @AJW Sure, here are the docs: https://developer.android.com/reference/android/os/Handler#post(java.lang.Runnable) https://developer.android.com/reference/android/os/Handler#postDelayed(java.lang.Runnable,%20java.lang.Object,%20long) . You use the postDelayed if you wish for the runnable to run at least X ms fro now. – android developer Nov 10 '21 at 23:13
  • Excellent, I appreciate the info. – AJW Nov 10 '21 at 23:15
  • 1
    @AJW Typo . Meant "from". I guess you know. :) – android developer Nov 11 '21 at 21:18
  • @androiddeveloper How can i run something not in the main thread??? – KJEjava48 Dec 04 '21 at 13:15
  • @KJEjava48 Many ways to do it. The basic one is to create a new `Thread` class and either implement `run` on it or provide a `Runnable` instance to it, and then call `start()` on this `Thread` instance. In Kotlin there is a very short way to do it, using just `thread{ runCodeHere() }` . – android developer Dec 04 '21 at 14:26
7

You can check

if(Looper.myLooper() == Looper.getMainLooper()) {
   // You are on mainThread 
}else{
// you are on non-ui thread
}
Lovekush Vishwakarma
  • 2,661
  • 20
  • 23
3

Allow me to preface this with: I acknowledged this post has the 'Android' tag, however, my search had nothing to do with 'Android' and this was my top result. To that end, for the non-Android SO Java users landing here, don't forget about:

public static void main(String[] args{
    Thread.currentThread().setName("SomeNameIChoose");
    /*...the rest of main...*/
}

After setting this, elsewhere in your code, you can easily check if you're about to execute on the main thread with:

if(Thread.currentThread().getName().equals("SomeNameIChoose"))
{
    //do something on main thread
}

A bit embarrassed I had searched before remembering this, but hopefully it will help someone else!

NekoKikoushi
  • 476
  • 5
  • 16
2

First of all check It is main Thread or not

In Kotlin

fun isRunningOnMainThread(): Boolean {
    return Thread.currentThread() == Looper.getMainLooper().thread
}

In Java

static boolean isRunningOnMainThread() {
  return Thread.currentThread().equals(Looper.getMainLooper().getThread());
}
Kumar Santanu
  • 374
  • 1
  • 5
  • 11
1

you can verify it in android ddms logcat where process id will be same but thread id will be different.

Vishwanath.M
  • 6,105
  • 10
  • 41
  • 55
1

Xamarin.Android port: (C#)

public bool IsMainThread => Build.VERSION.SdkInt >= BuildVersionCodes.M
    ? Looper.MainLooper.IsCurrentThread
    : Looper.MyLooper() == Looper.MainLooper;

Usage:

if (IsMainThread) {
    // you are on UI/Main thread
}
Mehdi Dehghani
  • 9,600
  • 6
  • 56
  • 58
1

just log this line, it should print "main".

Thread.currentThread().name

shubham chouhan
  • 301
  • 1
  • 5
-1

A simple Toast message works also as a quick check.

-6

You can try Thread.currentThread().isDaemon()

  • I am not sure the UI thread is a daemon but I will believe you on this one. But how will you make the difference with a Daemon Thread that I could (but should not) create. – AxelH Nov 29 '16 at 13:43
  • I tested in my web app, it shows that UI thread is a Daemon thread. I put some debug break points in eclipse environment and verified it. Thread detail shown as Thread[http-bio-8080-exec-7,5,main]. Clicked on some UI pages and checked the debug point. – Shailendra Singh Dec 01 '16 at 07:34
  • Also, even if in the thread name details its showing 'main' but calling setDaemon(true) on thread object will make it daemon. – Shailendra Singh Dec 01 '16 at 07:37
  • You didn't read the good part ... I wasn't doubting (completly) about it being a Daemon, I was telling that you can't make the differences with an other Daemon thread like this. – AxelH Dec 01 '16 at 07:43
  • Put another way: a main thread may be a daemon thread, but not all daemon threads are the main thread. (Identifying the main thread is what is being asked here.) –  May 18 '17 at 16:09
  • Also, it's important to note that the main thread being a daemon is not under programmer control, and an API or VM change could result in this assertion being untrue. –  May 18 '17 at 16:13