Como verificar se o segmento atual não é o principal


Respostas:


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

se isso retornar true, você estará no thread da interface do usuário!


Como você executa esse código em junho?
— John Sardinha

123

você pode usar o código abaixo para saber se o thread atual é UI / Main thread ou não

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

ou você também pode usar isso

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

Aqui está uma pergunta semelhante


8
Deve-se considerar o último como a opção mais segura, pois não há garantia de que qualquer encadeamento arbitrário esteja associado a um Looper (assumindo que o encadeamento principal esteja sempre associado a um looper)?
— Janus Varmarken

Looper.myLooper()retornará nulo se o encadeamento não estiver associado a um Looper. Portanto, ambos são seguros e têm o mesmo resultado, mas o primeiro é um pouco mais lento enquanto ele pesquisa dentro de um mapa para descobrir o looper e seu thread associado e fazer outras coisas.
— Saeed Masoumi

59

A melhor maneira é a maneira mais clara e robusta: *

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

Ou, se a plataforma de tempo de execução for o nível 23 da API (Marshmallow 6.0) ou superior:

Looper.getMainLooper().isCurrentThread()

Veja a API do Looper . Observe que a chamada Looper.getMainLooper()envolve sincronização (consulte a fonte ). Você pode evitar a sobrecarga armazenando o valor de retorno e reutilizando-o.

   * credit greg7gkb e 2cupsOfTech


O que você quer dizer com "na API 23 ou superior"? Isso não faz muito sentido para me..Also a mesma resposta exata foi publicado por AAnkit, abaixo ..
— Mike

@ Mike Obrigado, eu corrigi o bit API. AAnkit realmente é favorável Looper.myLooper() == Looper.getMainLooper(), o que eu acho que é menos claro. Eu credito greg7gkb.
— Michael Allan

11
deve ser uma comparação com == ou igual a (), pois o Android Studio gera um aviso?
— Juls

@ 2cupsOfTech No segundo pensamento, esse é um bom conselho. Atualmente, os dois testes são os mesmos em tempo de execução porque o Thread não substitui equalse, portanto, volta a ser ==, mas isso pode mudar no futuro. Então eu corrigi a resposta.
— Michael Allan

25

Resumindo as soluções, acho que é a melhor:

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

E, se você deseja executar algo no thread da interface do usuário, pode usar o seguinte:

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

6

Você pode checar

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

2

Permitam-me que antecipe isso com: Eu reconheci que este post tem a tag 'Android', no entanto, minha pesquisa não teve nada a ver com 'Android' e esse foi o meu principal resultado. Para esse fim, para os usuários SO Java que não são do Android que chegam aqui, não se esqueça:

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

Depois de definir isso, em outro lugar do seu código, você pode verificar facilmente se está prestes a executar no thread principal com:

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

Um pouco envergonhado, eu tinha procurado antes de lembrar isso, mas espero que ajude alguém!


1

você pode verificá-lo no android ddms logcat, onde a identificação do processo será a mesma, mas a identificação da thread será diferente.


1

Xamarin.Androidporta: ( C#)

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

Uso:

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

-6

Você pode tentar Thread.currentThread (). IsDaemon ()


Não tenho certeza de que o thread da interface do usuário seja um daemon, mas acreditarei em você. Mas como você fará a diferença com um Daemon Thread que eu poderia (mas não deveria) criar.
— AxelH

Eu testei no meu aplicativo da web, ele mostra que o thread da interface do usuário é um thread do Daemon. Coloquei alguns pontos de interrupção de depuração no ambiente eclipse e verifiquei. Detalhes do segmento mostrados como Tópico [http-bio-8080-exec-7,5, principal]. Clicou em algumas páginas da interface do usuário e verificou o ponto de depuração.
— Shailendra Singh

Além disso, mesmo que nos detalhes do nome do encadeamento seja exibido 'main', mas chamar setDaemon (true) no objeto de encadeamento o tornará daemon.
— Shailendra Singh

Você não leu a parte boa ... Eu não estava duvidando (completamente) de ser um Daemon, estava dizendo que você não pode fazer as diferenças com outro segmento do Daemon como este.
— AxelH

Em outras palavras: um encadeamento principal pode ser um encadeamento daemon, mas nem todos os encadeamentos daemon são o encadeamento principal. (Identificar o segmento principal é o que está sendo pedido aqui.)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.