현재 스레드가 메인 스레드가 아닌지 확인하는 방법


답변:


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

이것이 true를 반환하면 UI 스레드에있는 것입니다!


이 코드를 junit에서 어떻게 실행합니까?
John Sardinha

122

아래 코드를 사용하여 현재 스레드가 UI / 메인 스레드인지 아닌지 알 수 있습니다

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

또는 이것을 사용할 수도 있습니다

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

비슷한 질문이 있습니다


8
임의의 스레드가 루 퍼와 연관되어 있다는 보장이 없기 때문에 후자를 더 안전한 옵션으로 고려해야합니까 (주 스레드가 항상 루 퍼와 관련되어 있다고 가정)?
Janus Varmarken

Looper.myLooper()스레드가 루 퍼와 연관되지 않은 경우 널을 리턴합니다. 따라서 둘 다 안전하고 동일한 결과를 갖지만 첫 번째는 맵 내부를 검색하여 루 퍼와 관련 스레드를 찾고 다른 작업을 수행하는 동안 약간 느립니다.
Saeed Masoumi

59

가장 좋은 방법은 가장 명확하고 강력한 방법입니다. *

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

또는 런타임 플랫폼이 API 레벨 23 (Marshmallow 6.0) 이상인 경우 :

Looper.getMainLooper().isCurrentThread()

Looper API를 참조하십시오 . 호출 Looper.getMainLooper()에는 동기화가 포함됩니다 ( 소스 참조). ). 리턴 값을 저장하고 재사용하여 오버 헤드를 피할 수 있습니다.

   * 신용 greg7gkb2cupsOfTech


"API 23 이상"이란 무엇을 의미합니까? 그것은 저에게 이해가되지 않습니다. 또한 똑같은 대답은 아래 AAnkit에 의해 게시되었습니다.
Mike

@ Mike 감사합니다. API 비트를 수정했습니다. AAnkit은 실제로을 선호합니다 Looper.myLooper() == Looper.getMainLooper(). 나는 greg7gkb를 신용합니다.
Michael Allan

1
Android Studio에서 경고가 발생하므로 == 또는 equals ()와 비교해야합니까?
2cupsOfTech

@ 2cupsOfTech 2 번째 생각에, 그것은 좋은 충고입니다. Thread 는 무시하지 않기 때문에 현재 두 테스트는 모두 런타임에 동일합니다.equals 하므로 다시로 넘어가 ==지만 나중에 변경 될 수 있습니다. 그래서 대답을 수정했습니다.
Michael Allan

25

솔루션을 요약하면 이것이 최선이라고 생각합니다.

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

UI 스레드에서 무언가를 실행하려면 다음을 사용할 수 있습니다.

new Handler(Looper.getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
       //this runs on the UI thread
    }
});

6

당신은 확인할 수 있습니다

if(Looper.myLooper() == Looper.getMainLooper()) {
   // You are on mainThread 
}else{
// you are on non-ui thread
}

2

이 글의 머리말을 허용합니다.이 게시물에 'Android'태그가 있다는 것을 알았지 만 검색시 'Android'와는 아무런 관련이 없으며 이것이 최고의 결과였습니다. 이를 위해 Android 이외의 Java 사용자가 방문하는 경우 다음 사항을 잊지 마십시오.

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

코드의 다른 곳에서 이것을 설정하면 다음을 사용하여 메인 스레드에서 실행할 것인지 쉽게 확인할 수 있습니다.

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

내가 이것을 기억하기 전에 검색했던 약간 당혹 스러웠지만, 다른 누군가를 도울 수 있기를 바랍니다!


1

프로세스 ID는 동일하지만 스레드 ID는 다른 안드로이드 ddms logcat에서 확인할 수 있습니다.


1

Xamarin.Android포트 : ( C#)

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

용법:

if (IsMainThread) {
    // you are on UI/Main thread
}

-6

Thread.currentThread (). isDaemon ()을 시도 할 수 있습니다


UI 스레드가 데몬인지 확실하지 않지만이 스레드를 믿습니다. 그러나 내가 만들 수는 있지만 데몬 스레드와 어떻게 차이를 만들 수 있습니까?
AxelH

내 웹 응용 프로그램에서 테스트했는데 UI 스레드가 데몬 스레드임을 보여줍니다. 일식 환경에 디버그 중단 점을 넣고 확인했습니다. 스레드 세부 사항은 스레드 [http-bio-8080-exec-7,5, main]로 표시됩니다. 일부 UI 페이지를 클릭하고 디버그 지점을 확인하십시오.
Shailendra Singh

또한 스레드 이름에 'main'을 표시하지만 스레드 객체에서 setDaemon (true)을 호출하면 데몬이됩니다.
Shailendra Singh

당신은 좋은 부분을 읽지 못했습니다 ... 나는 그것이 데몬이라는 것에 대해 (완전히) 의심하지 않았습니다.
AxelH

다시 말해서, 메인 스레드는 데몬 스레드 일 수 있지만 모든 데몬 스레드가 기본 스레드는 아닙니다. (주요 스레드를 식별하는 것이 여기에서 요청됩니다.)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.