In our project we need to obtain some data (which will be stored) before doing operations. In case the data was obtained more than 15 minutes ago we have to refresh it.
We're using Kotlin + Anko coroutines in order to do that. The idea (assuming the data was obtained at some point before) is that:
The method gets called and checks when we got the data. If it was less than 15 min ago, returns it. If not, obtain it asynchronously (it's a network operation), store it and return it.
Since we can't do anything before getting the refreshed data, the refresh must be synchronous (althrough the network operation itself is async).
We've this 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)
return@async obtainedData
}
// ???????
} else {
val input = ObjectInputStream(this.openFileInput("data.dat"))
return input.readObject() as Data
}
} catch (e: Exception) {
return null
}
}
How can we make the function wait for the result outside the async(UI) block? That return is needed, but we have no clue about what should we put there. We've tried with the getCompleted() method of the Deferred object ( return asyncUser.getCompleted()) but it ends up crashing because it returns null.
Thank you!
I see a couple of ways to do this. One is to use the
kotlinx.coroutines.experimental
methodrunBlocking
:Depending on use case, you may even be able to simplify this to:
Another way is to use a basic Java
CountDownLatch
: