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.