Hadif Hatta
Hadif Hatta

Reputation: 107

How to wait and continue execution in Kotlin

basically, I am trying to continue execution right after the ad is finished.

Currently, I am using delay which is not really convenient. Some user won't wait or simply dismiss the activity while the delays happen.

My current approach:

override fun onRequestStarted() {
    showAd()
}

private fun Context.showAd(): Boolean {
    mInterstitialAd?.fullScreenContentCallback = object : FullScreenContentCallback() {

    /** Some other function **/

    override fun onAdShowedFullScreenContent() {
        isAdWatched = true
    }
}

override fun onRequestIntent() {
    GlobalScope.launch {
        delay(10000L)

        if (isAdWatched) {
            isAdWatched = false
            super.onRequestIntent(intent)
        }
    }
}

Upvotes: 0

Views: 1614

Answers (1)

Tenfour04
Tenfour04

Reputation: 93511

You can convert callback-based APIs to suspend functions.

To create a suspend function that returns when the callback fires. For this example, I'm assuming you only want to await the return from the ad, whether or not it was watched. I haven't tested this, but the documentation implies that this particular function onAdDismissedFullScreenContent is the only one you need to respond to to know when the ad is finished (or never loaded).

/** Show the ad and suspend until it is dismissed. */
suspend fun InterstitialAd.showAndAwait(activity: Activity) = suspendCoroutine<Unit> { cont ->
    fullScreenContentCallback = object : FullScreenContentCallback() {
        override onAdDismissedFullScreenContent() {
            cont.resume(Unit)
        }
    }
    showAd(activity)
}

You will have to change your design so the functionality isn't split between these two functions that you overrode. I don't know how you're calling these two functions, so I can't exactly suggest what you need to change. But ultimately, to do what you described, you would have a single function to call that launches a coroutine, and in the coroutine calls the above suspend function to show the ad and then does whatever you want to do next. Something like this:

fun foo() {
    lifecycleScope.launch {
        mInterstitialAd?.showAndAwait()
        doSomethingAfterReturnedFromAd()
    }
}

Never use GlobalScope. In the latest version of Kotlin Coroutines, it shows a compiler warning when you use it, although it's not quite deprecated because there are a few very specific cases where it might have useful applications. You should use lifecycleScope for this.

Upvotes: 2

Related Questions