From dc31181387b7de551620b702cd59d108d2d486f2 Mon Sep 17 00:00:00 2001 From: Abdelilah El Aissaoui Date: Sat, 6 Aug 2022 03:46:09 +0200 Subject: [PATCH] Improved avatar loading Now avatar loading checks first if there is a cached avatar and before showing the placeholder, to avoid showing the placeholder for a moment when a cached version is available. This will reduce CPU usage by a tiny bit since the placeholder won't have to be rendered. --- .../kotlin/app/images/NetworkImageLoader.kt | 44 ++++++++++++++----- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/src/main/kotlin/app/images/NetworkImageLoader.kt b/src/main/kotlin/app/images/NetworkImageLoader.kt index 36e120f..0fbc20f 100644 --- a/src/main/kotlin/app/images/NetworkImageLoader.kt +++ b/src/main/kotlin/app/images/NetworkImageLoader.kt @@ -20,12 +20,18 @@ object NetworkImageLoader { private val loadingImagesSemaphore = Semaphore(MAX_LOADING_IMAGES) private val cache: ImagesCache = InMemoryImagesCache + fun loadCachedImage(url: String): ImageBitmap? { + val cachedImage = cache.getCachedImage(url) + + return cachedImage?.toComposeImage() + } + suspend fun loadImageNetwork(url: String): ImageBitmap? = withContext(Dispatchers.IO) { try { - val cachedImage = cache.getCachedImage(url) + val cachedImage = loadCachedImage(url) if (cachedImage != null) - return@withContext cachedImage.toComposeImage() + return@withContext cachedImage loadingImagesSemaphore.acquireAndUse { val imageByteArray = loadImage(url) @@ -34,7 +40,7 @@ object NetworkImageLoader { } } catch (ex: Exception) { - if(ex !is FileNotFoundException) + if (ex !is FileNotFoundException) ex.printStackTrace() } @@ -54,24 +60,40 @@ object NetworkImageLoader { @Composable fun rememberNetworkImageOrNull(url: String, placeHolderImageRes: String? = null): ImageBitmap? { val networkImageLoader = NetworkImageLoader + val cacheImageUsed = remember { ValueHolder(false) } + var image by remember(url) { - val placeHolderImage = if (placeHolderImageRes != null) - useResource(placeHolderImageRes) { + val cachedImage = networkImageLoader.loadCachedImage(url) + + val image: ImageBitmap? = when { + cachedImage != null -> { + cacheImageUsed.value = true + cachedImage + } + placeHolderImageRes != null -> useResource(placeHolderImageRes) { Image.makeFromEncoded(it.toByteArray()).toComposeImageBitmap() } - else - null + else -> null + } - mutableStateOf(placeHolderImage) + return@remember mutableStateOf(image) } LaunchedEffect(url) { - val networkImage = networkImageLoader.loadImageNetwork(url) - if (networkImage != null) - image = networkImage + if(!cacheImageUsed.value) { + val networkImage = networkImageLoader.loadImageNetwork(url) + + if (networkImage != null && !cacheImageUsed.value) { + image = networkImage + } + } + } return image } fun ByteArray.toComposeImage() = Image.makeFromEncoded(this).toComposeImageBitmap() + + +internal class ValueHolder(var value: T) \ No newline at end of file