Vorwort
Kotlin Coroutines ist eine neue asynchrone API, die von Kotlin gestartet wurde. Nicht die beste Lösung für alle Probleme, aber hoffentlich wird es in vielen Fällen die Dinge ein wenig erleichtern. Hier werde ich einfach den spezifischen Nutzungsplan dieser Bibliothek in Android zeigen. Ich werde unten nicht viel sagen. Schauen wir uns die detaillierte Einführung zusammen an.
Einführung von Coroutinen
// Fügen Sie den folgenden Code im Android-Knoten in der Build.gradle-Datei der Anwendung Kotlin hinzu.
Das erste Coroutines -Beispiel
Normalerweise laden wir ein Bild in ImageView, und die asynchrone Ladeaufgabe lautet wie folgt:
Fun Loadbitmapfrommediastore (ImageId: int, ImagesBaseuri: Uri): bitmap {val uri = uri.withAppendedPath (ImagesBaseuri, ImageId.toString ()) return medide.images.media.gingbitmap (contentResolver, uri)}}}}Diese Methode muss im Hintergrund -Thread ausgeführt werden, da sie zu einer IO -Operation gehört, was bedeutet, dass wir viele Lösungen haben, um die Hintergrundaufgabe zu starten, und sobald die Methode eine Bitmap zurückgibt, müssen wir sie sofort in der ImageView anzeigen.
ImageView.SetImageBitMap (Bitmap)
Diese Codezeile muss im Haupt -Thread ausgeführt werden, sonst stürzt er ab.
Wenn die oben genannten drei Codezeilen zusammen geschrieben sind, wird das Programm festgefahren oder abgestürzt, was von der angemessenen Auswahl der Threads abhängt. Schauen wir uns als nächstes an, wie Coroutinen mit Kotlin dieses Problem löst:
Val Job = Start (Hintergrund) {val uri = uri.withAppendedPath (ImagesBaseuri, ImageId.toString ()) VAL bitmap = mediDStore.images.Media.gbitbitmap (contentResolver, Start (UI) {ImageView.setimageBitMap (Bitmap)}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}.Das Wichtigste hier ist der Hintergrund und die Benutzeroberfläche von Start () und Parametern. Start () bedeutet, eine Coroutine zu erstellen und zu starten. Mit dem CoroutineContext des Hintergrundparameters wird die Ausführung im Hintergrund -Thread sichergestellt, um sicherzustellen, dass die Anwendung nicht stecken oder abgestürzt ist. Sie können einen CoroutineContext deklarieren, wie unten gezeigt.
Internal Hintergrund = newfixed threadpoolContext (2, "BG")
Dies erstellt einen neuen Kontext und verwendet zwei reguläre Threads bei der Ausführung seiner Aufgaben.
Als nächstes starten Sie (UI), der eine weitere Coroutine auslöst, die auf Android ausgeführt wird
Hauptfaden.
Stornierbar
Die nächste Herausforderung besteht darin, Dinge im Zusammenhang mit dem Aktivitätserklärungzyklus zu bewältigen. Wenn Sie eine Aufgabe laden und die Aktivität verlassen, bevor sie ausgeführt wurde, wird beim Aufrufen von imageView.setImageBitmap(bitmap) Absturz verursacht. Daher müssen wir die Aufgabe abbrechen, bevor wir die Aktivität verlassen. Hier verwenden wir den Rückgabewert der Start () -Methode. Wenn die Aktivität die OnStop -Methode aufruft, müssen wir den Job verwenden, um die Aufgabe zu stornieren.
Job.cancel ()
Es ist so, als würde man entsorgen, wenn Sie Rxjava verwenden und die Abbrechen -Funktion aufrufen, wenn Sie Asynctask verwenden.
Lifecycleobserver
Android -Architekturkomponenten bieten Android -Entwicklern viele leistungsstarke Bibliotheken, von denen eine die Lebenszyklus -API ist. Es bietet uns eine einfache Möglichkeit, den Lebenszyklus von Aktivitäten und Fragmenten in Echtzeit zu hören. Definieren wir den Code, der mit Coroutinen verwendet werden soll.
Klasse coroutinelifecyclelistener (Val Deferred: Deferred <*>): LifeCycleObserver {@onlifecycleEvent (lifecycle.event.on_destroy) Fun CancelCoroutine () {if (! Deferred.iscancelled) {deferred.cancel ()}}}}}}}}}}}}}}}}}}}}Wir erstellen eine Lebenszykluer -Erweiterungsfunktion:
Fun <T> Lifecycleuner.load (Loader: () -> T): Deferred <T> {val deferred = async (context = Hintergrund, start = coroutinestart.lazy) {lader ()} LifeCycle.Addobserver (coroutInelifecyclelistener (Deferred) (Deferred) returned }ver (coroutInelifecyclelisten (deferred)) Es gibt zu viele neue Dinge in dieser Methode, und ich werde sie einzeln erklären:
Jetzt können wir load() in einer Aktivität oder einem Fragment aufrufen und auf die Lebenszykluselemente aus dieser Funktion zugreifen und unseren Coroutinelifecyclelistener als Beobachter hinzufügen.
Die Lastmethode erfordert einen Lader als Parameter, der einen allgemeinen Typ T zurückgibt. In der Lastmethode nennen wir eine andere Coroutine -Ersteller async () -Funktion, die den Coroutine -Kontext des Hintergrunds verwendet, um Aufgaben im Hintergrund -Thread auszuführen. Beachten Sie, dass diese Methode einen weiteren Parameter start = coroutInestart.lazy hat, was bedeutet, dass die Coroutine nicht sofort ausgeführt wird, bis sie aufgerufen wird.
Coroutine gibt dann ein Defered<T> -Objekt an den Anrufer zurück, der unserem vorherigen Job ähnlich ist, aber es kann auch einen Verzögerungswert wie JavaScript -Versprechen oder Future <T> in einer regulären Java -API mit sich bringen, und noch besser hat sie eine Warteverfahren.
Als nächstes definieren wir eine andere Erweiterungsfunktion then() , diesmal definieren wir sie über Deferen<T> , was der Typ ist, der nach unserer Lastmethode oben zurückgegeben wird. Es dauert auch eine Lambda als Parameter mit dem Namen Block, das ein einzelnes Objekt vom Typ T als Parameter nimmt.
Infix Fun <T> aufgeschoben <t> .then (Block: (t) -> Einheit): Job {return start (context = ui) {block ([email protected] ())}}} Diese Funktion erstellt eine weitere Korutine mit launch() , die diesmal auf dem Haupt -Thread ausgeführt wird. Das an diese Coroutine übergebene Lambda (namentlicher Block) nimmt den Wert des abgeschlossenen aufgeschobenen Objekts als Parameter. Wir rufen await() um die Ausführung dieser Coroutine auszusetzen, bis das aufgeschobene Objekt einen Wert zurückgibt.
Hier wird Coroutine so beeindruckend. Der auf den Hauptdhreop await() erfolgt, blockiert jedoch nicht die weitere Ausführung dieses Threads. Es wird einfach die Ausführung der Funktion pausieren, bis sie fertig ist, wenn sie wieder aufnimmt und den verzögerten Wert an die Lambda übergibt. Wenn die Coroutine suspendiert wird, kann der Hauptfaden weiterhin andere Dinge ausführen. Die wartende Funktion ist ein Kernkonzept in Coroutine, was das Ganze so magisch erzeugt.
Der in load() hinzugefügte Lebenszyklusbeobachter storniert die erste Coroutine, nachdem wir onDestroy() in unserer Aktivität aufgerufen haben. Dies führt auch dazu, dass die zweite Coroutine storniert wird, wodurch block() aufgerufen wird.
Kotlin Coroutine DSL
Jetzt, da wir zwei Erweiterungsfunktionen und eine Klasse haben, die die Absage von Coroutine abwickelt, lassen Sie uns sehen, wie man sie benutzt:
Load {LoadbitMapFrommediArtore (ImageId, ImagesBaseuri)} dann {ImageView.SetImageBitMap (It)}} Im obigen Code übergeben wir die Lambda -Methode an die Lastfunktion, mit der die LOADBitMapFrommediAsore -Methode aufgerufen wird, die auf dem Hintergrund -Thread ausgeführt werden muss, bis die Methode eine Bitmap zurückgibt, und der Rückgabewert der Lastmethode wird Deferred<Bitmap> .
Als Erweiterungsfunktion verwendet then() -Methode die Infix -Deklaration. Obwohl die Lastmethode Deferred<Bitmap> zurückgegeben wird, wird sie an die dann an die dann Methode ein Bitmap -Rückgabewert übergeben, sodass wir im Rahmen der damaligen Methode imageView.setImageBitmap(it) direkt aufrufen können.
Der obige Code kann für alle asynchronen Aufrufe verwendet werden, die im Hintergrund -Thread auftreten müssen, und wenn der Rückgabewert wie im obigen Beispiel in den Haupt -Thread zurückgegeben werden sollte. Es macht nicht mehrere Anrufe wie Rxjava, aber es ist einfacher zu lesen und kann viele der häufigsten Fälle abdecken. Jetzt können Sie so etwas sicher tun, ohne sich Sorgen zu machen, dass Sie in jedem Anruf Kontextlecks oder Verarbeitung von Threads verursachen.
Laden {restapi.fetchData (Abfrage)} dann {adapter.display (it)}}Dann () und Load () Methoden sind nur die Spitze des Eisbergs dieser neuen Bibliothek, aber ich hoffe, dass in zukünftigen Kotlin-basierten Android-Bibliotheken etwas Ähnliches erscheint, sobald die Coroutine-Version eine stabile Version erreicht. Vor diesem Fall können Sie den oben genannten Code verwenden oder ändern oder Anko Coroutines lesen. Ich habe auch eine vollständigere Version auf Github veröffentlicht. (https://github.com/erikhellman/kotlinasyncwithCoroutines (lokaler Download)).
Zusammenfassen
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Referenzwert für das Studium oder die Arbeit eines jeden hat. Wenn Sie Fragen haben, können Sie eine Nachricht zur Kommunikation überlassen. Vielen Dank für Ihre Unterstützung bei Wulin.com.