如何将这个(AdsWizz)Kotlin回调函数封装在一个程序中



我是协程的新手,很难弄清楚如何正确地将现有回调封装在协程中。

我的目标是能够做到以下几点:

lifecycleScope.launch {
withContext(Dispatchers.Main) {
val theResult = getPreRollAd()      //1. call this suspending func and wait for result
doSomethingWithResult(theResult)    //2. now that the result is returned from AdsWizz API (below), do something with it 
}
}

这是我想"包装"的AdsWizzneneneba API调用:

val adReqInterface: AdRequestHandlerInterface =  object :
AdRequestHandlerInterface {
override fun onResponseError(error: AdswizzSDKError) {
Timber.e("onResponseError $error")
}
override fun onResponseReady(adResponse: AdResponse) {
Timber.d( "onResponseReadySingleAd")
//this contains the url to the ad, title, etc..
!!!*** I WANT TO RETURN THE adResponse.mediaFile?.source string back to "theResult" variable above (in lifecycleScope.launch {.... )

}
}
try {
AdswizzSDK.getAdsLoader().requestAd(adReqParams, adReqInterface)
} catch (e: IllegalArgumentException) {
Timber.d( "IllegalArgumentException")
} catch (e: SecurityException) {
Timber.d( "SecurityException")
} catch (e: Exception) {
Timber.d( "other exception")
e.printStackTrace()
}

我尝试过使用suspendCoroutine {...进行包装,但没有任何效果。真的很感激有人帮助你是实现这一目标的正确途径。

正确的方法是使用suspendCancellableCoroutine。它可以返回结果,也可以在出现异常时取消。

suspend fun getPreRollAd(): AdResponse {
return suspendCancellableCoroutine {
...
val adReqInterface: AdRequestHandlerInterface =  object : AdRequestHandlerInterface {
override fun onResponseError(error: AdswizzSDKError) {
Timber.e("onResponseError $error")
it.cancel(error)
}
override fun onResponseReady(adResponse: AdResponse) {
Timber.d( "onResponseReadySingleAd")
it.resume(adResponse)
}
}
AdswizzSDK.getAdsLoader().requestAd(adReqParams, adReqInterface)
}
}

viewModelScope.launch {
val result = try {
getPreRollAd()
} catch(e: Throwable) {
null
}
...
}

最新更新