In unserem Projekt müssen wir einige Daten erhalten (die gespeichert werden), bevor Sie Operationen ausführen. Falls die Daten vor mehr als 15 Minuten abgerufen wurden, müssen wir sie aktualisieren.Kotlin & Anko Koroutinen: Rückkehr außerhalb Async
Wir verwenden Kotlin + Anko Coroutinen, um das zu tun. Die Idee (unter der Annahme, dass die Daten zu einem früheren Zeitpunkt erhalten wurden) lautet:
Die Methode wird aufgerufen und überprüft, wann wir die Daten bekommen haben. Wenn es vor weniger als 15 Minuten war, wird es zurückgegeben. Falls nicht, besorge es asynchron (es ist eine Netzwerkoperation), speichere es und gib es zurück.
Da wir nichts tun können, bevor die aktualisierten Daten abgerufen werden, muss die Aktualisierung synchron sein (auch wenn die Netzwerkoperation selbst asynchron ist).
Wir haben diesen Code:
fun Context.retrieveInfo(api: Api?): User? {
try {
// For sake of simplification the real conditional check is removed
if (time > 15) {
val context = this
val asyncUser = async(UI) {
val obtainData: Deferred<Data?> = bg {
api?.obtainData(sphelper.getDefaultUser(context))
}
val obtainedData = storeAndRetrieve(obtainData.await(), context)
[email protected] obtainedData
}
// ???????
} else {
val input = ObjectInputStream(this.openFileInput("data.dat"))
return input.readObject() as Data
}
} catch (e: Exception) {
return null
}
}
Wie können wir die Funktion Warten auf das Ergebnis außerhalb der Asynchron (UI) machen blockieren? Diese Rückkehr ist notwendig, aber wir haben keine Ahnung, was wir dort hinstellen sollten. Wir haben es mit der Methode getCompleted() des Deferred-Objekts versucht (return asyncUser.getCompleted()), aber es stürzt am Ende ab, weil es null zurückgibt.
Vielen Dank!
Ich habe die vereinfachte Version und die CountDownLatch ausprobiert und beide funktionieren gut. Vielen Dank! –
Ich habe gelesen, dass runBlocking ist für Testzwecke, nicht ideal für Endprodukte. –