Android: Che cosa fa la pubblicazione di un runnable da un altro thread sul thread principale effettivamente?

Quindi, come dice il titolo: Che cosa accade in realtà quando si inserisce un runnable da un altro thread sul thread principale?

Ho visto molte domande su come farlo e come funzionano le basi. Ma ho avuto difficoltà a trovare una spiegazione esatta di ciò che accade quando si mette un runnable sul MessageQueue. Funziona quando è il turno di Runnable, certo. Ma quando è questo?

  • Compilazione di un'applicazione semplice indossabile in Android Studio - WatchActivity non trovato
  • adb logcat: Aumenta la lunghezza massima del messaggio
  • Modo universale per scrivere sulla scheda SD esterna su Android
  • Android copia il progetto esistente con un nuovo nome in Android Studio
  • errore "imansible get BatchedBridge, assicurati che il tuo pacco sia confezionato correttamente" all'inizio dell'app
  • Android ottiene l'indirizzo IP di un hotspot che fornisce il dispositivo
  • Così per esempio:
    Supponendo che sia presente un button che lancia una richiesta ASync e la richiesta restituisce e triggers un runnable / callback che viene eseguito su MainThread. Che succede? Il runnable viene aggiunto ad un MessageQueue e viene eseguito quando è 'tempo'. Ma quando è 'tempo'? Cosa succede se premo un altro button che esegue un'attività di block semi-lungo sul MainThread appena prima che la richiesta Async inserisca il runnable su MainThread? Attende che la logica sul mio button di block sia completata? Lo interrompe? Interviene il codice runnable con il codice del mio codice di block? Cosa succede esattamente?

    La ragione principale per cui sto chiedendo è che posso avere una migliore comprensione di quali considerazioni devo tenere in mente per evitare errori dovuti al multithreading. (In particolare il caso delle vecchie richieste che interessano pagine già aggiornate)

  • Passare i dati del referrer attraverso l'intento cromato al gioco google
  • ByteBuffer non rilascia la memory
  • lancio app facebook da altre app
  • android: onClick non funziona con ProGuard
  • C'è un modo per cambiare android: windowSoftInputMode valore della class java?
  • Sviluppo Android: combinazione di piastrelle / bitmap in una bitmap
  • 2 Solutions collect form web for “Android: Che cosa fa la pubblicazione di un runnable da un altro thread sul thread principale effettivamente?”

    Innanzitutto, è necessario capire che cosa è la class Message . Un object Message contiene tra gli altri campi quanto segue:

      Handler target; // a handler that enqueued the message long when; // the time at which the message is to be processed [RUNNABLE] Runnable callback; = [SWITCHED] int what, int arg1, int arg2, Bundle data... bool isAsynchronous; // I will talk about it in the end 

    Quello che ho contrassegnato con [RUNNABLE] e [SWITCHED] rappresenta i due mezzi non sovrapposti per l'elaborazione di un Message . Se il callback non è nullo, tutti i campi [SWITCHED] vengono ignorati. Se il callback è nullo rispetto al Message è definito da campi [SWITCHED] ed è elaborato sia nel handleMessage() override del handleMessage() o nel handleMessage() del Handler.Callback il gestore è stato inizializzato con.

    Il MessageQueue viene ordinato dal field when . Il Looper non dequeerà e procede un messaggio finché l'ora corrente, misurata da SystemClock.uptimeMillis , è maggiore o uguale al tempo memorizzato nel field del messaggio.

    Quando si chiama Handler#post(Runnable r) le seguenti cose:

    1. Viene visualizzato un Message dalla piscina (un semplice elenco statico collegato nella class Message )

    2. Il tuo Runnable è assegnato al field di callback del messaggio.

    3. when field è semplicemente impostato sull'ora corrente se non è stato passato alcun ritardo o tempo specifico

    4. Il Message viene messo in cima alla MessageQueue . Se when è prima di quello della testa della coda diventa una nuova testa. Se non lo è, viene inserito al centro in modo che il MessageQueue ordinato di when

    5. Il Looper che era in un ciclo non terminante che dequeuava i messaggi dalla coda e li procede in sequenza (senza intreccio), infine, depone il nostro messaggio e chiama dispatchMessage() sul gestore che ha originariamente pubblicato il Runnable .

    6. Il gestore decide se il messaggio è [RUNNABLE] o [ SWITCHED] e lo procede di conseguenza. In particolare, chiamano run() sul callback se è presente

    Questo dovrebbe rispondere alle tue domande sul comportmento del tuo Runnable pubblicato sulla Runnable dell'interface utente durante l'attività di block – beh, no, non interrompe l'attività in corso né interviene . Tutto ciò che accade sul thread entra in primo luogo nei clic del button MessageQueue o dei tuoi Runnables personalizzati da submit da altri thread. In fondo non c'è modo che potrebbe accadere in qualche altro modo: Looper.loop() fa solo il filo occupato con il suo loop for(;;) .

    Ci sono modi per cambiare i messaggi che ordinano però.

    Per esempio, c'è un concetto interessante di barriera di sincronizzazione nel quadro Looper / Handler. Una barriera di sincronia è da un convegno solo un Message con un target nullo (quindi è fondamentalmente solo un tipo di bandiera, non ci è gestore per spedirlo). Se viene inserito nella coda con postSyncBarrier() , l'integer process di dequalifica delle modifiche, finché la barriera di sincronizzazione viene rimossa dalla coda con removeSyncBarrier() . I Messages non contrassegnati come isAsynchronous verranno ignorati e non vengono rimossi e trattati affatto. Invece, la coda verrà sottoposta a scansione finché non viene trovato il messaggio con isAsynchronous = true . Sarà quindi programmato in base al suo when e elaborato quando sarà il suo tempo.

    Inoltre, è ansible call un Handler#postAtFrontOfQueue() auto-esplicativo Handler#postAtFrontOfQueue() , però, come indicato nella documentazione

    Questo metodo è solo per l'uso in particolari circostanze particolari: può facilmente affamare la coda dei messaggi, causare problemi di ordinazione o avere altri effetti collaterali imprevisti.

    Suggerisco di sfogliare il codice sorgente di tutte le classi citate. Si legge come un buon libro di fiction.

    Ci sono un sacco di altri runnables eseguiti da MainThread, ad esempio l'aggiornamento dell'interface utente, gli events di contatto. Il 'tempo' è quando il runnable inviato è pronto per essere rimosso. Se qualcuno di essi fosse venuto in precedenza, il tuo runnable aspetterà.

    Non esiste una cosa del genere come l'interruzione. Il tuo button invierà uno scoppio di runnables, uguali a submit lo stesso numero di runnables da molti thread diversi.

    Se si dispone di un messaggio non corto (ciò che contiene la parola LUNGA è dannoso per l'interface utente), l'operazione bloccherà l'esecuzione di altre attività ricorrenti inviate nella coda, la maggior parte dei quali viene spesso dimostrata senza aggiornamenti (per l'esecuzione che è indeterminata) l'UI a tutti o sparire se è questione di scoppio di runnables che l'esecuzione richiede più di 8ms.

    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.