Aprendizagem relacionada ao manipulador (três) o manipulador deve estar de volta

Barreira de sincronização Android-Handler

https://www.jianshu.com/p/2fb96d4e0cd5

1. A barreira de sincronização do mecanismo de mensagem

Depois que o Handler define a barreira de sincronização, ele pode interceptar a aquisição e distribuição de mensagens de sincronização do Looper. Depois de entrar na barreira de sincronização, o Looper só obterá e processará mensagens assíncronas, se não houver mensagem assíncrona entrará no estado de bloqueio.

A barreira de sincronização do mecanismo de mensagem está, na verdade, bloqueando a mensagem de sincronização e apenas permitindo a passagem da mensagem assíncrona. A maneira de abrir a barreira de sincronização é chamar o seguinte método:

MessageQueue#postSyncBarrier()

O código-fonte para criar uma mensagem de sincronização é o seguinte:

@TestApi
public int postSyncBarrier() {
    // 这里传入的时间是从开机到现在的时间戳
    return postSyncBarrier(SystemClock.uptimeMillis());
}
/**
 * 这就是创建的同步屏障的方法
 * 同步屏障就是一个同步消息,只不过这个消息的target为null
 */
private int postSyncBarrier(long when) {
    // Enqueue a new sync barrier token.
    // We don't need to wake the queue because the purpose of a barrier is to stall it.
    synchronized (this) {
        final int token = mNextBarrierToken++;
        // 从消息池中获取Message
        final Message msg = Message.obtain();
        msg.markInUse();
        // 初始化Message对象的时候,并没有给Message.target赋值,
        // 因此Message.target==null
        msg.when = when;
        msg.arg1 = token;

        Message prev = null;
        Message p = mMessages;
        if (when != 0) {
            // 这里的when是要加入的Message的时间
            // 这里遍历是找到Message要加入的位置
            while (p != null && p.when <= when) {
                // 如果开启同步屏障的时间(假设记为T)T不为0,且当前的同步
                // 消息里有时间小于T,则prev也不为null
                prev = p;
                p = p.next;
            }
        }
        // 根据prev是否为null,将msg按照时间顺序插入到消息队列的合适位置
        if (prev != null) { // invariant: p == prev.next
            msg.next = p;
            prev.next = msg;
        } else {
            msg.next = p;
            mMessages = msg;
        }
        return token;
    }
}

Você pode ver aqui que o destino não recebe um valor quando o objeto Message é inicializado, portanto, a origem de target == null pode ser encontrada. Desta forma, uma mensagem target == null pode ser inserida, que é uma barreira de sincronização.
Então, depois de abrir a barreira da mensagem, como as chamadas mensagens assíncronas são tratadas?
O processamento final da mensagem é, na verdade, no poller de mensagem Looper # loop (), e no loop loop (), MessageQueue # next () é chamado para buscar a mensagem da fila de mensagens.

No próximo método de MessageQueue.java:

Enquanto isso, primeiro julga-se que esta msg é uma mensagem síncrona,! Msg.isAsynchronous (), se a mensagem for síncrona, a próxima msg será executada.

A partir do método MessageQueue.next acima, pode-se ver que quando a fila de mensagens abre a barreira de sincronização (ou seja, o identificador é msg.target == null), o mecanismo de mensagem dará prioridade às mensagens assíncronas ao processar mensagens. Desta forma, a barreira de sincronização desempenha um papel de filtragem e prioridade

Conforme mostrado na figura acima, existem mensagens síncronas e assíncronas (parte amarela) e uma parede (parte vermelha da barreira síncrona) na fila de mensagens. Com a existência da barreira de sincronização, as duas mensagens assíncronas msg_2 e msg_M podem ser processadas primeiro, enquanto as mensagens síncronas subsequentes, como msg_3, não serão processadas. Então, quando essas mensagens de sincronização podem ser processadas? Você precisa remover esta barreira de sincronização primeiro, ou seja, chamar MessageQueue # removeSyncBarrier ()

Como enviar mensagens assíncronas
Normalmente, quando usamos Handler para enviar mensagens, essas mensagens são todas mensagens síncronas. Se quisermos enviar mensagens assíncronas, use um dos seguintes construtores ao criar Handler (async passa verdadeiro)

public Handler(boolean async);
public Handler(Callback callback, boolean async);
public Handler(Looper looper, Callback callback, boolean async);

Então, todas as mensagens enviadas através do manipulador se tornarão mensagens assíncronas

 

 

 

 

 

 

 

 

 

 

 

 

 

Acho que você gosta

Origin blog.csdn.net/cpcpcp123/article/details/115261890
Recomendado
Clasificación