I thought I understood kotlin coroutines :man-face...
# coroutines
t
I thought I understood kotlin coroutines 🤦‍♂️
I have this function in my repository of my android application
Copy code
override suspend fun displayItem(contentId: Long): DisplayItemState =
        withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
            val encodedUrl = encode("${BuildConfig.MY_CONTENT_C_URL}$contentId", StandardCharsets.UTF_8.name())
            DisplayItemState(Intent(Intent.ACTION_VIEW, Uri.parse("${BuildConfig.MY_MOBILE_CLICK}${loginToken()!!}?url=$encodedUrl")))
        }
which is called in this
init{}
of my viewModel private lateinit var notificationDisplayItem: DisplayItemState init { if (isNotification) viewModelScope.launch { when (notificationAction) { VALUE_ARG_SPECIALTY_NOTIFICATION_ACTION_VIEW -> notificationDisplayItem = repository.displayItem(contentId!!) VALUE_ARG_SPECIALTY_NOTIFICATION_ACTION_SAVE -> TODO("Should never occur as save broadcast receiver") VALUE_ARG_SPECIALTY_NOTIFICATION_ACTION_DISCARD -> TODO("Should never occur as discard broadcast receiver") else -> TODO("Unexpected notification action $notificationAction") } } }
the issue is the
lateinit
variable
notificationDisplayItem
is not being initialized how can i get my code to "wait" for the call to
repository.displayItem(contentId!!)
to respond
s
If I’m understanding right, you want the constructor to suspend? That’s not possible, especially since this constructor will presumably be invoked by the platform
Why does
displayItem
need to suspend, though?
t
oh , thats a good question 🤔
p
does the function loginToken() also suspend? If so, displayItem needs to suspend
s
Didn’t spot that, it’s very well hidden 😄
t
does the function loginToken() also suspend? If so, displayItem needs to suspend
yes it does
how i got to this "position" is that android studio flags the
encode
call with "P_*ossibly blocking call in non-blocking context could lead to thread starvation*_"
and i was investigating how i could resolve this i have a feeling
encode
is not that big an issue
s
Where is that
encode
function coming from? There are a few things that could cause that warning, e.g. declaring certain types of exception
t
Copy code
import java.net.URLEncoder.encode
s
Hah 😄 so it looks like the warning is because that method declares
UnsupportedEncodingException
, which extends
IOException
. The IDE sees that and assumes that IOException = IO = blocking, which is a pretty big leap 😄
Your feeling is correct, you can safely suppress that warning
t
Screenshot 2023-03-09 at 17.08.59.png
thanks for your time 😄
r
Just to answer the original question, in the more general case where you do actually need to do something suspending on init and potentially wait for it later you can use a Deferred:
Copy code
private val notificationDisplayItem: Deferred<DisplayItemState> = viewModelScope.async {//suspending work}
where it's needed:
Copy code
notificationDisplayItem.await() //returns result, suspends or throws