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?
-
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
15 Answers
Looper.myLooper() == Looper.getMainLooper()
if this returns true, then you're on the UI thread!

- 21,744
- 6
- 60
- 75
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.
}
-
10Should 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
-
1`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
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

- 3,731
- 23
- 31
-
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
-
1@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
-
2should this be a comparison with == or equals() as Android Studio is raising a warning ? – 2cupsOfTech Jul 28 '17 at 14:19
-
1@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
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
}
});

- 14,208
- 10
- 51
- 80

- 114,585
- 152
- 739
- 1,270
-
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
-
-
-
@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
You can check
if(Looper.myLooper() == Looper.getMainLooper()) {
// You are on mainThread
}else{
// you are on non-ui thread
}

- 3,035
- 23
- 25
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!

- 496
- 5
- 16
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());
}

- 603
- 1
- 7
- 14
In addition to all previous answers
inline fun <T> ensureNotOnMainThread(block: () -> T): T {
check(Thread.currentThread() != Looper.getMainLooper().thread) { "This function cannot be called on main thread" }
return block()
}
allows to wrap any method with it, following example :
fun isInDataBase(id: String) = ensureNotOnMainThread { db.contains(id) }

- 1,219
- 10
- 17
you can verify it in android ddms logcat where process id will be same but thread id will be different.

- 6,235
- 11
- 42
- 56
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
}

- 10,970
- 6
- 59
- 64
So another answer to join the company, for some extension file in kotlin:
import android.os.Looper.getMainLooper
import java.lang.Thread.currentThread
val Thread.isMain get() = getMainLooper().thread == this
val isThreadMain get() = getMainLooper().thread == currentThread()

- 5,887
- 1
- 47
- 66
A simple Toast message works also as a quick check.

- 85
- 1
- 1
-
-
`Toast.makeText(activity, "Hello main thread", Toast.LENGTH_LONG).show();` – Stefan Irndorfer Dec 21 '21 at 12:44
A coroutines-based, Android-agnostic approach:
val onMainThread: Boolean
get() = Thread.currentThread() === try {
runBlocking(Dispatchers.Main.immediate) {
Thread.currentThread()
}
} catch (e: IllegalStateException) {
// No main dispatcher has been registered; not in an Android context?
null
}

- 1,130
- 15
- 15
-
Care to elaborate @Renetik? Can you suggest a better solution in a non-Android context? – Stephen Talley Jun 24 '23 at 21:56
You can try Thread.currentThread().isDaemon()

- 483
- 5
- 9
-
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