現在のスレッドがメインスレッドでないかどうかを確認する方法


回答:


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

これがtrueを返す場合は、UIスレッドを使用しています。


このコードをjunitでどのように実行しますか?
John Sardinha

123

以下のコードを使用して、現在のスレッドが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 2016年

Looper.myLooper()スレッドがルーパーに関連付けられていない場合はnullを返します。したがって、どちらも安全で同じ結果が得られますが、最初のものはマップ内を検索してルーパーとそれに関連するスレッドを見つけ、他のことを行う間、少し遅くなります。
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により投稿されたme..Alsoにあまり意味がないこと
マイク

@Mikeありがとう、APIビットを修正しました。AAnkitは実際にはを支持Looper.myLooper() == Looper.getMainLooper()していますが、これはあまり明確ではないと思います。私はgreg7gkbを信用しています。
Michael Allan

1
Android Studioが警告を出しているので、これは==またはequals()との比較ですか?
2cupsOfTech 2017

@ 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 SO 以外の 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が異なるandroid 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 2016年

私は自分のWebアプリでテストしましたが、UIスレッドがデーモンスレッドであることを示しています。いくつかのデバッグブレークポイントをEclipse環境に配置して検証しました。Thread [http-bio-8080-exec-7,5、main]として表示されるスレッドの詳細。一部のUIページをクリックして、デバッグポイントを確認しました。
Shailendra Singh

また、スレッド名に「main」と表示されていても、スレッドオブジェクトでsetDaemon(true)を呼び出すと、デーモンになります。
Shailendra Singh

あなたは良い部分を読んでいません...私はそれがデーモンであることについて(完全に)疑っていませんでした、私はあなたがこのような他のデーモンスレッドと違いを作ることができないと言っていました。
AxelH 16

言い換えると、メインスレッドはデーモンスレッドである可能性がありますが、すべてのデーモンスレッドがメインスレッドであるとは限りません。(メインスレッドの識別はここで尋ねられるものです。)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.