I am new to anko and coroutines so excuse me if I am asking something trivial :)
So what I am trying to do is have the user click a button and then I want to download a JSON from the internet, store it locally and parse it. Since both operations can take considerable time I thought to use anko coroutines.
So first question is:
1. Can I use nested doAsync calls, calling the 2nd doAsync in the UIThread of the first one? I tried it and it seems to work but it feels wrong so I was trying to find a more elegant way
Example:
doAsync {
downloadFileFromUrl(fileUrl)
uiThread {
doAsync {
IOUtils.parseFile(context!!)
val database = AppDatabase.getInstance(context!!)
val results = database.resultsDao().all
uiThread {
//show Results
}
}
}
}
2. While searching a solution for my problem I found doAsyncResult. If 1 it's not correct, is this is the correct approach? I tried already to use it but with Boolean I get errors. See below:
private fun downloadFileFromUrl(fileUrl: String): Boolean {
try{
//Download file. No doAsync calls here.
//The procedure just returns true if successful or false in case of any errors
return true
} catch (e: Exception) {
Log.e("Error: ", e.message)
return false
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
parseButton.setOnClickListener {
try {
val downloadFileResult: (AnkoAsyncContext<Boolean>.() -> Boolean) = {
::downloadFileFromUrl.invoke(fileUrl)
}
val downloadFileResultFutureValue: Future<Boolean> = doAsyncResult(null, downloadFileResult)
//Continue processing if downloadFileResultFutureValue is true
} catch (e: IOException) {
e.printStackTrace()
}
}
}
This line
val downloadFileResultFutureValue: Future<Boolean> = doAsyncResult(null, downloadFileResult)
does not compile with the following error which I don't understand how to fix:
Type inference failed: Cannot infer type parameter T in
fun <T, R> T.doAsyncResult
(
exceptionHandler: ((Throwable) → Unit)? = ...,
task: AnkoAsyncContext<T>.() → R
)
: Future<R>
None of the following substitutions
receiver: Boolean
arguments:
(
((Throwable) → Unit)?,
AnkoAsyncContext<Boolean>.() → Boolean
)
receiver: BlankFragment
arguments:
(
((Throwable) → Unit)?,
AnkoAsyncContext<BlankFragment>.() → Boolean
)
can be applied to
receiver: BlankFragment
arguments:
(
Nothing?,
AnkoAsyncContext<Boolean>.() → Boolean
)
Thanks in advance
Doing this:
doAsync {
// 1. Something
uiThread {
// 2. Nothing
doAsync {
Indeed doesn't make much sense, unless (2) is not nothing, and you just omitted some code.
If you didn't, you can just stay with this version:
doAsync {
downloadFileFromUrl(fileUrl)
IOUtils.parseFile(context!!)
val database = AppDatabase.getInstance(context!!)
val results = database.resultsDao().all
uiThread {
//show Results
}
}
Since parseFile()
depends on downloadFileFromUrl()
anyway, and everything runs in a coroutine, you don't become more concurrent by adding this back-and-forth.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With