0

I am using ion, a library for Android. As shown in ion-kotlin, one can use a method called await() like so:

fun getFiles(files: Array<String>) = async {
    for (file in files) {
        Ion.with(context)
        .load(file)
        .asString()
        .await()
    }
}

I copy pasted that exact function into my MainActivity class, as a test. However, I got the error "unresolved reference: await" in Android Studio.

This was confusing because my app's build.gradle file has the following two lines:

implementation 'com.koushikdutta.ion:ion:2.+'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.22.5'

This brings me to my first question, how can I use the .await() method in the ion library?

I thought that maybe I had to manually download AsyncAwait.kt, which was the only file in the source folder of ion-kotlin.

So, I downloaded that file and placed it in my project's package. I changed the package declaration at the top of the downloaded file from package com.koushikdutta.ion.kotlin to package com.example.vroy1.recylerviewtest.

That seemed to partially solve the problem because I no longer had the "unresolved reference: await" error in Android Studio.

But, the file AsyncAwait.kt refuses to compile. I am getting several errors.

One of the errors is occurring at an import statement at the top of the file. The error is:

Screen_Shot

This brings me to my second question. If the only way to use .await() is to manually download AsyncAwait.kt, how can I fix this error so the file will compile?

Community
  • 1
  • 1
Foobar
  • 7,458
  • 16
  • 81
  • 161

1 Answers1

0

I would suggest you to define some Utility function like this

suspend fun <T> customAsync(block: suspend CoroutineScope.() -> T): Deferred<T> {
  val deferred: Deferred<T> = async(CommonPool) { block() }
  return deferred
}

suspend fun <T> asyncAwait(block: suspend CoroutineScope.() -> T): T = customAsync(block).await()

and then you can define the getFiles() function in the normal way(No need to make it async) and if you want to execute it in different thread then call that function inside asyncAwait {} like this

 launch(UI) {
    val result = asyncAwait {
      getFiles(listOfStrings)
    }
  }
pk4393
  • 322
  • 3
  • 16
  • This answer is wrong in two ways: 1. it recommends to use async-await against an already asynchronous API. 2. `async(block).await()` is not what `async` is for. Use `withContext(CommonPool)` instead. – Marko Topolnik May 21 '18 at 11:07
  • @Marko Topolnik my answer is not for the case where getFiles() is not async. Its for the case where getFiles() is a normal function, which is already mentioned in my answer. And as you can see ```async(block).await()``` is calling the above function which already has ```val deferred: Deferred = async(CommonPool) { block() }``` – pk4393 May 21 '18 at 13:27
  • Why did you write the answer here, then, which is about an async API? Furthermore, you say "if you want to execute it in a different thread", but your `async(block: ...)` already submits the block to a different thread. – Marko Topolnik May 21 '18 at 13:34
  • @Marko Topolnik naming of my async method looks like the internal function of Coroutine so now I have changed the naming so that there will be no confusion – pk4393 May 21 '18 at 13:58
  • I wasn't confused by your naming. `customAsync` submits the block to the `CommonPool`. The block executes on another thread, whether you call `await()` afterwards or not. – Marko Topolnik May 21 '18 at 14:05
  • calling `asyncAwait { getFiles(listOfStrings) }` has exactly the same effect as `withContext(CommonPool) { getFiles(listOfStrings) }`. There was no need to involve `Deferred`. – Marko Topolnik May 21 '18 at 14:10