Análise aprofundada avançada avançada do Android do mecanismo de mensagem

Análise aprofundada avançada avançada do Android do mecanismo de mensagem

Tempo de leitura: 8 minutos

Você está sentado quieto? Indo dirigir


Escreva na frente

O conteúdo compartilhado hoje é uma análise aprofundada do mecanismo de mensagem do Android.Algumas pessoas perguntaram, algumas funções podem ser usadas? Por que analisar o código-fonte subjacente? O que Xiaolu diz a você hoje é que muitos projetos de código aberto não precisam mais de nós para construir rodas, e como é estúpido reconstruí-las. No entanto, o código-fonte subjacente do Android e a realização de algumas funções nos permitem aprender o padrão subjacente e a implementação lógica.

A coisa mais importante sobre aprender programação é o pensamento lógico.Mesmo se você pode alcançar qualquer função, você não pode fazer nada com pouca habilidade de pensamento lógico. Sua capacidade de raciocínio lógico é fraca e sua altura foi determinada na rota técnica.

Mecanismo de mensagem do Android

O mecanismo de mensagem do Android significa principalmente que a operação do Handler precisa do suporte do MessageQueue e do Looper subjacentes.

(1) A tradução chinesa de MessageQueue é uma fila de mensagens. Fornece inserção e exclusão de trabalho externamente na forma de uma fila. Embora seja chamada de fila de mensagens, a estrutura de armazenamento interno não é uma fila real, mas uma estrutura de dados de lista vinculada individualmente para armazenar a lista de mensagens.

(2) A tradução chinesa do Looper é loop, nós o chamamos de loop de mensagem. Como MessageQueue é apenas uma unidade de armazenamento, ela não processará mensagens. O looper compensa esta função. Looper irá procurar por novas mensagens em um loop infinito e processar as mensagens se houver, caso contrário, ele esperará para sempre.

Mapa mental de aprendizagem:

Os mapas mentais em artigos futuros são cuidadosamente organizados por Xiaolu para todos, de modo que cada artigo compartilhado tenha uma estrutura clara, o que conduz à revisão e organização.

Análise aprofundada avançada avançada do Android do mecanismo de mensagem

1. Visão geral do mecanismo de mensagem Android

O mecanismo de mensagem do Android se refere principalmente ao mecanismo operacional de Handler e ao processo de trabalho de MessageQueue e Looper anexado ao Handler. A principal função do Handler é mudar uma tarefa para um thread especificado para execução.

Visão geral

(1) Pensando: Por que o Android fornece essa função?

Resposta: Como o Android estipula que o thread de IU só pode ser acessado no thread principal, se a IU for acessada no thread filho, o programa lançará uma exceção.

(2) Código-fonte: Depois de verificar o código-fonte, o método checkThread () verifica se a UI de atualização está atualizada no thread principal e lança uma mensagem de exceção para lembrar o desenvolvedor (acredito que isso tenha sido encontrado no desenvolvimento).

(3) Processo: devido às restrições acima, isso requer que os desenvolvedores atualizem a IU no thread principal, mas o Android também recomenda não fazer um trabalho muito demorado no thread principal, caso contrário, o aplicativo não responderá ao ANR. Considerando esta situação, quando extraímos algumas informações do servidor e as exibimos na IU, faremos o trabalho de pull no thread filho. Após a conclusão do pull, a IU não pode ser atualizada diretamente no thread filho. Sem o Handler, then we Na verdade, não há como alternar o trabalho de acesso à IU para o thread principal para execução. Portanto, a principal razão pela qual o sistema nos fornece o Handler é resolver a contradição de que a IU não pode ser acessada no thread filho.

(4) Pergunta:

① 为什么不能再子线程中更新 UI? 
答 : 因为 Android 的 UI 控件不是线性安全的。如果在多线程中并发的访问可能会导致 UI 控件处于不可预期的状态。

② 为什么不对 UI 控件的访问加上锁机制呢? 

答 :首先,加上锁机制会让访问 UI 变的复杂,其次锁机制会降低 UI 的访问效率,因为锁机制会阻塞某些线程的执行。

A maneira mais simples e eficiente é usar um modelo de thread único para lidar com as operações da IU. Você só precisa alternar o thread de execução do acesso à IU por meio de Handlerr.

Como funciona o manipulador

Quando o Handler é criado, o Looper atual será usado para construir o sistema de loop de mensagem interno.Se não houver nenhum Looper atualmente, um erro será relatado.

Como resolver os problemas acima? Dois métodos:

① Basta criar o Looper para o tópico atual.
② Também é possível criar um Handler no thread do Looper.

princípio de trabalho

(1) Processo de criação do Handler: Depois que o Handler é criado, o MessageQueue interno e o Looper trabalham juntos com o Handler e, em seguida, um Runnable é entregue ao Looper dentro do Handler para processamento por meio do método post do Handler; também pode ser processado por meio o método send do Handler envia uma mensagem, que também é processada pelo Looper. Na verdade, o método Post é finalmente completado pelo método send.

(2) O processo de trabalho do método send: quando o método send do Handler é chamado, ele chamará o método enqueueMessage de MessageQueue para colocar a mensagem na fila de mensagens, e então o Looper processará a mensagem quando encontrar um novo mensagem e, finalmente, o Runnable da mensagem ou o método handlerMessage de Handler será chamado.

Análise aprofundada avançada avançada do Android do mecanismo de mensagem

Dois, a análise do mecanismo de mensagem do Android

Como funciona a fila de mensagens

A fila de mensagens no Android se refere principalmente a MessageQueue, MessageQueue inclui principalmente duas operações: inserir e excluir. A implementação interna da fila de mensagens não é uma fila. Na verdade, a fila de mensagens é mantida por meio da estrutura de dados de uma lista unida individualmente. A lista unida individualmente tem vantagens na inserção e exclusão.

① Inserir (enqueueMessage): insere uma mensagem na fila de mensagens. (A implementação do código-fonte é a inserção de uma lista unida)

② Excluir (próximo): Retire uma mensagem da fila de mensagens e remova-a da fila de mensagens. (O próximo é um método de loop infinito, a fila de mensagens é bloqueada sem informações e a lista unicamente vinculada é excluída quando uma nova mensagem chega)

Como funciona o Lopper

Looper desempenha a função de loop de mensagem no mecanismo de mensagem do Android. Sua função é verificar constantemente se há novas mensagens do MessageQueue. Se houver mensagens, elas serão processadas imediatamente e, se não houver mensagens, serão bloqueadas .

(1) Método de construção Looper

① Crie uma fila de mensagens MessageQueue.

② Salve o objeto do segmento atual.

(2) Como criar Looper para um tópico

(Trabalho de manuseio requer Looper, sem Looper, um erro será relatado)

 ① 通过 Looper.prepare() 方法为线程创建一个 Looper 。

 ② 通过 Looper.loop() 方法来开启消息循环。

(3) Outra maneira de criar tópicos

① 主线程 Looper 的获取。 Looper 这个方法主要给线程也就是 ActivityThread 创建 Looper 使用的,本质也是通过 prepare 来实现的,由于主线程的 Looper 比较特殊,所以 Looper 提供了一个 getMainLopper 的方法获取主线程的 Looper。

② Looper 的退出。****Looper 提供了两个方法:quit 方法和 quitSafely 方法。

A diferença entre os dois: Sair sai do Looper diretamente.

E quitSafely apenas define uma marca de saída e sai após processar as mensagens na fila de mensagens.

(4) O princípio de realização do método Looper.loop ()

loop 是一个死循环,唯一能跳出循环的方法就是 MessageQueue 的 next 方法返回了 null。当 Looper 的 quit 方法被调用时,MessageQueue 的 quit 方法或者 quitSafely 方法就会通知消息队列退出,当消息队列被标记为退出状态时,next 就会返回一个 null。Looper 是必须退出的,否则 loop 会永远循环下去。 

O método de loop chamará o próximo método de MessageQueue para obter a mensagem.Se o MessageQueue não tiver mensagens, o próximo estará em um estado de bloqueio e o método de loop também estará em um estado de bloqueio.

Explique o princípio de funcionamento do Handler em detalhes

A principal tarefa do Handler é enviar e receber mensagens. A mensagem pode ser enviada através de uma série de métodos de postagem e de uma série de métodos de envio.A série de métodos de postagem é finalmente realizada através de uma série de métodos de envio.

Código:


 1public class HandlerActivity extends Activity {
 2
 3    @Override
 4    protected void onCreate(@Nullable Bundle savedInstanceState) {
 5        super.onCreate(savedInstanceState);
 6        setContentView(R.layout.activity_main);
 7
 8        //开启线程
 9        handler();
10    }
11    //主线程
12    Handler handler = new Handler(){
13
14        @Override
15        public void handleMessage(Message msg) {
16            super.handleMessage(msg);
17            switch (msg.what) {
18                case 1:
19                    // 获取Message里面的复杂数据
20                    Bundle date = new Bundle();
21                    date = msg.getData();
22                    String name = date.getString("name");
23                    int age = date.getInt("age");
24                    String sex = date.getString("sex");
25                    //这里是主线程,可进行对UI的更新
26                    textView.setText(name)
27            }
28        }
29    };
30
31    //子线程
32    public void handler(){
33        new Thread(new Runnable() {
34            @Override
35            public void run() {
36                Message message = new Message();
37                message.what = 1;
38
39                // Message对象保存的数据是Bundle类型的
40                Bundle data = new Bundle();
41                data.putString("name", "李文志");
42                data.putInt("age", 18);
43                data.putString("sex", "男");
44                // 把数据保存到Message对象中
45                message.setData(data);
46                // 使用Handler对象发送消息
47                handler.sendMessage(message);
48            }
49        }).start();
50    }
51}

enviar mensagens

Por meio da análise do código-fonte, o processo de Handler de enviar uma mensagem consiste apenas em inserir uma parte da informação na fila de mensagens, e o próximo método de MessageQueue retornará essa informação ao Looper, e o Looper irá processá-la imediatamente após receber o mensagem, e Looper irá entregá-la para Handler para processar a mensagem, o método dispatchMessage de Handler será chamado e, em seguida, Handler entrará no estágio de processamento de mensagem.

Processamento de mensagens

Análise aprofundada avançada avançada do Android do mecanismo de mensagem

Uma análise aprofundada do código-fonte de dispatchMessage, o Handler processa a mensagem da seguinte maneira:

① Primeiro verifique se o retorno de chamada de Message é nulo.Se não for nulo, processe a mensagem através de handlerCallback. (O retorno de chamada da mensagem é um objeto Runnable d, que é na verdade o parâmetro Runnable passado pelo método post)

② Em segundo lugar, verifique se mCallback é nulo.Se não for nulo, chame o método handlerMessage de mCallback para processar a mensagem. O retorno de chamada é uma interface.

③ Por meio do Callback, podemos usar os seguintes métodos para criar objetos Handle.


1Handler handler = new Handler(callback);

O significado desta criação é criar uma instância, mas não precisa derivar uma subclasse de Handler.

④ No entanto, em nosso desenvolvimento diário, frequentemente derivamos uma subclasse de Handler e sobrescrevemos seu método handleMessage para processar mensagens específicas.Se você não quiser criar uma subclasse derivada, você pode usar Callback.

Loop de mensagem do tópico principal

O thread principal do Android é ActivityThread. O método de entrada do thread principal é main. No método principal, o sistema usará Looper.prepareMainLooper (); para criar o Looper e MessageQueue do thread principal e usar Looper.loop ( ) para abrir a mensagem do ciclo do thread principal.

Depois que o loop de mensagem do thread principal é iniciado, ActivityThread também precisa de um Handler para interagir com a fila de mensagens.Este Handler é ActivityThread.H. ActivityThread se comunica entre processos por meio de ApplicationThread e AMS. Depois que o AMS conclui a solicitação de ActvityThread por meio da comunicação entre processos, ele chamará de volta o método Binder em ApplicationThread e, em seguida, ApplicationThread enviará uma mensagem para H, e H mudará a lógica em ApplicationThread para ActivityThread ao receber a mensagem. Execute no meio, ou seja, mude para o thread principal para execução. Este processo é o modelo de loop de mensagem do thread principal.

Acho que você gosta

Origin blog.51cto.com/15064450/2602814
Recomendado
Clasificación