Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Compose] Warm the task cache before LaunchedEffect runs #1891

Merged
merged 3 commits into from
Sep 8, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,10 @@ fun rememberLottieComposition(
): LottieCompositionResult {
val context = LocalContext.current
val result by remember(spec) { mutableStateOf(LottieCompositionResultImpl()) }
LaunchedEffect(spec) {
// Warm the task cache. We can start the parsing task before the LaunchedEffect gets dispatched and run.
// The LaunchedEffect task will join the task created inline here via LottieCompositionFactory's task cache.
remember(spec, cacheKey) { lottieTask(context, spec, cacheKey, isWarmingCache = true) }
LaunchedEffect(spec, cacheKey) {
var exception: Throwable? = null
var failedCount = 0
while (!result.isSuccess && (failedCount == 0 || onRetry(failedCount, exception!!))) {
Expand Down Expand Up @@ -115,7 +118,23 @@ private suspend fun lottieComposition(
fontFileExtension: String,
cacheKey: String?,
): LottieComposition {
val task = when (spec) {
val task = requireNotNull(lottieTask(context, spec, cacheKey, isWarmingCache = false)) {
"Unable to create parsing task for $spec."
}

val composition = task.await()
loadImagesFromAssets(context, composition, imageAssetsFolder)
loadFontsFromAssets(context, composition, fontAssetsFolder, fontFileExtension)
return composition
}

private fun lottieTask(
context: Context,
spec: LottieCompositionSpec,
cacheKey: String?,
isWarmingCache: Boolean,
): LottieTask<LottieComposition>? {
return when (spec) {
is LottieCompositionSpec.RawRes -> {
if (cacheKey == DefaultCacheKey) {
LottieCompositionFactory.fromRawRes(context, spec.resId)
Expand All @@ -131,16 +150,19 @@ private suspend fun lottieComposition(
}
}
is LottieCompositionSpec.File -> {
val fis = withContext(Dispatchers.IO) {
@Suppress("BlockingMethodInNonBlockingContext")
FileInputStream(spec.fileName)
}
when {
spec.fileName.endsWith("zip") -> LottieCompositionFactory.fromZipStream(
ZipInputStream(fis),
spec.fileName.takeIf { cacheKey != null },
)
else -> LottieCompositionFactory.fromJsonInputStream(fis, spec.fileName.takeIf { cacheKey != null })
if (isWarmingCache) {
// Warming the cache is done from the main thread so we can't
// create the FileInputStream needed in this path.
null
} else {
val fis = FileInputStream(spec.fileName)
when {
spec.fileName.endsWith("zip") -> LottieCompositionFactory.fromZipStream(
ZipInputStream(fis),
spec.fileName.takeIf { cacheKey != null },
)
else -> LottieCompositionFactory.fromJsonInputStream(fis, spec.fileName.takeIf { cacheKey != null })
}
}
}
is LottieCompositionSpec.Asset -> {
Expand All @@ -155,11 +177,6 @@ private suspend fun lottieComposition(
LottieCompositionFactory.fromJsonString(spec.jsonString, jsonStringCacheKey)
}
}

val composition = task.await()
loadImagesFromAssets(context, composition, imageAssetsFolder)
loadFontsFromAssets(context, composition, fontAssetsFolder, fontFileExtension)
return composition
}

private suspend fun <T> LottieTask<T>.await(): T = suspendCancellableCoroutine { cont ->
Expand Down