I've got much of my app working fine with "by lazy" initializers because everything magically happens in the order that is necessary.
But not all of the initializers are synchronous. Some of them are wrapping callbacks, which means I need to wait until the callback happens, which means I need runBlocking
and suspendCoroutine
.
But after refactoring everything, I get this IllegalStateException: runBlocking is not allowed in Android main looper thread
What? You can't block? You're killing me here. What is the right way if my "by lazy" happens to be a blocking function?
private val cameraCaptureSession: CameraCaptureSession by lazy {
runBlocking(Background) {
suspendCoroutine { cont: Continuation<CameraCaptureSession> ->
cameraDevice.createCaptureSession(Arrays.asList(readySurface, imageReader.surface), object : CameraCaptureSession.StateCallback() {
override fun onConfigured(session: CameraCaptureSession) {
cont.resume(session).also {
Log.i(TAG, "Created cameraCaptureSession through createCaptureSession.onConfigured")
}
}
override fun onConfigureFailed(session: CameraCaptureSession) {
cont.resumeWithException(Exception("createCaptureSession.onConfigureFailed")).also {
Log.e(TAG, "onConfigureFailed: Could not configure capture session.")
}
}
}, backgroundHandler)
}
}
}
Full GIST of the class, for getting an idea of what I was originally trying to accomplish: https://gist.github.com/salamanders/aae560d9f72289d5e4b49011fd2ce62b