2016-04-01 20 views
2

Ich möchte einen neuen Thread in onCreate erstellen und mit dem UI-Thread mit post auf einem View kommunizieren. Die post ed-Anweisungen scheinen jedoch nie ausgeführt zu werden. Hier ist ein kleines Beispiel:In UI-Thread schreiben

import android.app.Activity 
import android.os.Bundle 
import android.widget.TextView  
import kotlin.concurrent.* 
import org.jetbrains.anko.* 

class MainActivity: Activity(), AnkoLogger { 
    protected override fun onCreate(savedInstanceState: Bundle?) { 
    super.onCreate(savedInstanceState) 

    val view = TextView(this) 
    setContentView(view) 

    thread() { 
     info("before post") 
     view.post({ info("inside post") }) 
     info("after post") 
    } 
    } 
} 

im Protokoll der Suche, kann ich nur sehen before post und after post, aber nie inside post.

Was mache ich falsch?

+0

mb etwas in der 'info()' Implementierung? – AndroidEx

Antwort

5

Das zugrunde liegende Problem eigentlich nichts zu aktualisieren mit Kotlin zu tun.

Das Problem ist, dass nur View.post() Pläne seine Arbeit erfolgreich auf dem Haupt-Thread, wenn die Ansicht zur Zeit an die Ansichtshierarchie verbunden ist. Das letzte Anhängen der Ansicht findet nicht zur Zeit setContentView() statt. Es passiert etwas später.

In dem Fall, dass der Gegenstand Ansicht der post() ist derzeit nicht angebracht (wie es der Fall in dem Problem gezeigt ist), erzeugt die View eine RunQueue für den aktuellen Thread auf der Arbeit und Zeitplan (als Faden lokalen gespeichert) dass RunQueue.

So ist das Problem für die angegebene Probe wie folgt. Da View.post() nicht auf dem Haupt-Thread aufgerufen wird, erstellt es eine neue RunQueue für den aktuellen Nicht-Haupt-Thread ohne zu überprüfen, ob es von einem Looper (wie der Haupt-Thread) gerichtet ist. Dies bedeutet, dass die geplante Runnable im Wesentlichen in eine RunQueue geht, die nicht verarbeitet wird, bis eine Looper startet. In dem hier gezeigten Fall, dass Looper nie gestartet wird, wird der neue Thread beendet, und die Arbeit wird nie ausgeführt.

Wenn der neue Thread mit post verzögert wurde, nachdem die Ansicht angehängt wurde, z. B. wenn ein Klick darauf registriert wurde, kann die post wahrscheinlich die Arbeit am Hauptthread planen. Aber das ist hier nicht der Fall, da der Post auftritt 1) ​​bevor die Ansicht angehängt wird, und 2) auf einem anderen Thread, der sofort beendet wird.

+0

Was wäre der richtige Zeitpunkt, um 'thread()' zu starten, ohne sich auf Benutzerinteraktion zu verlassen, wie der Klick in Ihrem Beispiel? – Cactus

+1

Ich würde während der View onAttachedToWindow() oder eine registrierte View.OnAttachStateChangeListener. –

+0

Oh und BTW Ich hätte nie gedacht, dass es Kotlin-spezifisch wäre, aber habe es als Kotlin getaggt, damit jemand, der sich das minimale Repro-Beispiel anschaut, herausfinden kann, welche Sprache das ist. – Cactus

0

konnte ich durch Starten des Fadens selbst von einem post, um dieses Werk, das heißt

view.post({ 
    thread() { 
    info("before post") 
    view.post({ info("inside post") }) 
    info("after post") 
    } 
}) 

aber ich würde gerne verstehen, warum ich das tun musste.