coil-kt / coil

Image loading for Android and Compose Multiplatform.
https://coil-kt.github.io/coil/
Apache License 2.0
10.86k stars 668 forks source link

executeBlocking call from main thread Bug #2305

Closed nilufer32 closed 5 months ago

nilufer32 commented 5 months ago

Describe the bug A clear and concise description of what the bug is. I have a use case where I need to initialize an image request prior to calling AsyncImage. Id like to execute my Image Request before calling the AsyncImage, and I want to ensure that AsyncImage will only be called after the execute call has finished. I approached the requirement by using executeBlocking on the main thread as I wanted to ensure that the execution would happen immediately and my Image would be available before calling the Async Image composable. However, this causes my app to crash. After some digging I found the following note in javacompatibility.md: !!! Note ImageLoaders.executeBlocking will block the current thread instead of suspending. Do not call this from the main thread._ However, I'm wondering why in Kotlin I'm not able to preload an Image request on spot in a blocking way.

To Reproduce

@Composable
fun App() = AppTheme {
    setSingletonImageLoaderFactory { context -> getAsyncImageLoader(context) }
    val context = LocalPlatformContext.current
    val imageRequest = ImageRequest.Builder(
        context
    ).data("https://upload.wikimedia.org/wikipedia/commons/8/8c/Google.jpg").build()
    ImageLoader(context).executeBlocking(imageRequest)
    Box(
        Modifier
            .fillMaxSize()
            .background(Color.Cyan)
    ) {
        AsyncImage(
            model = ImageRequest.Builder(
                LocalPlatformContext.current
            ).data("https://upload.wikimedia.org/wikipedia/commons/8/8c/Google.jpg").build(),
            modifier = Modifier.fillMaxSize(),
            contentDescription = null
        )
    }
}
fun getAsyncImageLoader(context: PlatformContext) =
    ImageLoader.Builder(context).crossfade(false).logger(DebugLogger()).build()

Logs/Screenshots activityStartTrigger: not whiteListed failed to add asset path /data/app/com.test.app.wizardApp.androidApp-xDy==/base.apk Failed to find provider info for cn.teddymobile.free.anteater.den.provider

Version 3.0.0-alpha06

colinrtwhite commented 5 months ago

Check out this section on preloading for how to preload your request into memory.

However, I'm wondering why in Kotlin I'm not able to preload an Image request on spot in a blocking way.

Image requests can take a long time to execute and blocking the main thread will block the UI for a long time.

activityStartTrigger: not whiteListed

This exception isn't related to Coil.

nilufer32 commented 5 months ago

What if i’m loading a resource from compose resources??? why wouldn’t i be able to do that on the main thread in a blocking way

nilufer32 commented 5 months ago

If im loading from compose resources where no network loading is involved , I dont see why this can't be executed in a blocking way on the main thread

nilufer32 commented 5 months ago

@colinrtwhite is there a work around for this case or?