From 81e92e8a19607d2d373c8c10b032d50de70266e6 Mon Sep 17 00:00:00 2001 From: Sunlocker Date: Wed, 1 Mar 2023 16:31:45 +0800 Subject: [PATCH] Fixed the stream was not closed when the lottie animation hit the cache --- .../airbnb/lottie/LottieAnimationView.java | 2 ++ .../lottie/LottieCompositionFactory.java | 33 +++++++++++-------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java b/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java index 09c8c02812..4f451fb87e 100644 --- a/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java +++ b/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java @@ -470,6 +470,8 @@ public void setAnimationFromJson(String jsonString, @Nullable String cacheKey) { *

* This is particularly useful for animations loaded from the network. You can fetch the * bodymovin json from the network and pass it directly here. + *

+ * Auto-closes the stream. */ public void setAnimation(InputStream stream, @Nullable String cacheKey) { setCompositionTask(LottieCompositionFactory.fromJsonInputStream(stream, cacheKey)); diff --git a/lottie/src/main/java/com/airbnb/lottie/LottieCompositionFactory.java b/lottie/src/main/java/com/airbnb/lottie/LottieCompositionFactory.java index 8532394680..b74bcb1c8c 100644 --- a/lottie/src/main/java/com/airbnb/lottie/LottieCompositionFactory.java +++ b/lottie/src/main/java/com/airbnb/lottie/LottieCompositionFactory.java @@ -130,7 +130,7 @@ public static LottieTask fromUrl(final Context context, final LottieCompositionCache.getInstance().put(cacheKey, result.getValue()); } return result; - }); + }, null); } /** @@ -184,7 +184,7 @@ public static LottieTask fromAsset(Context context, final Str public static LottieTask fromAsset(Context context, final String fileName, @Nullable final String cacheKey) { // Prevent accidentally leaking an Activity. final Context appContext = context.getApplicationContext(); - return cache(cacheKey, () -> fromAssetSync(appContext, fileName, cacheKey)); + return cache(cacheKey, () -> fromAssetSync(appContext, fileName, cacheKey), null); } /** @@ -254,7 +254,7 @@ public static LottieTask fromRawRes(Context context, @RawRes @Nullable Context originalContext = contextRef.get(); Context context1 = originalContext != null ? originalContext : appContext; return fromRawResSync(context1, rawRes, cacheKey); - }); + }, null); } /** @@ -311,7 +311,7 @@ private static boolean isNightMode(Context context) { * @see #fromJsonInputStreamSync(InputStream, String, boolean) */ public static LottieTask fromJsonInputStream(final InputStream stream, @Nullable final String cacheKey) { - return cache(cacheKey, () -> fromJsonInputStreamSync(stream, cacheKey)); + return cache(cacheKey, () -> fromJsonInputStreamSync(stream, cacheKey), () -> closeQuietly(stream)); } /** @@ -343,7 +343,7 @@ public static LottieTask fromJson(final JSONObject json, @Nul return cache(cacheKey, () -> { //noinspection deprecation return fromJsonSync(json, cacheKey); - }); + }, null); } /** @@ -361,7 +361,7 @@ public static LottieResult fromJsonSync(JSONObject json, @Nul * @see #fromJsonStringSync(String, String) */ public static LottieTask fromJsonString(final String json, @Nullable final String cacheKey) { - return cache(cacheKey, () -> fromJsonStringSync(json, cacheKey)); + return cache(cacheKey, () -> fromJsonStringSync(json, cacheKey), null); } /** @@ -377,7 +377,7 @@ public static LottieResult fromJsonStringSync(String json, @N } public static LottieTask fromJsonReader(final JsonReader reader, @Nullable final String cacheKey) { - return cache(cacheKey, () -> fromJsonReaderSync(reader, cacheKey)); + return cache(cacheKey, () -> fromJsonReaderSync(reader, cacheKey), () -> Utils.closeQuietly(reader)); } @@ -417,7 +417,7 @@ public static LottieTask fromZipStream(final ZipInputStream i * @see #fromZipStreamSync(Context, ZipInputStream, String) */ public static LottieTask fromZipStream(Context context, final ZipInputStream inputStream, @Nullable final String cacheKey) { - return cache(cacheKey, () -> fromZipStreamSync(context, inputStream, cacheKey)); + return cache(cacheKey, () -> fromZipStreamSync(context, inputStream, cacheKey), () -> closeQuietly(inputStream)); } /** @@ -604,17 +604,24 @@ private static LottieImageAsset findImageAssetForFileName(LottieComposition comp * If not, create a new task for the callable. * Then, add the new task to the task cache and set up listeners so it gets cleared when done. */ - private static LottieTask cache( - @Nullable final String cacheKey, Callable> callable) { + private static LottieTask cache(@Nullable final String cacheKey, Callable> callable, + @Nullable Runnable onCached) { + LottieTask task = null; final LottieComposition cachedComposition = cacheKey == null ? null : LottieCompositionCache.getInstance().get(cacheKey); if (cachedComposition != null) { - return new LottieTask<>(() -> new LottieResult<>(cachedComposition)); + task = new LottieTask<>(() -> new LottieResult<>(cachedComposition)); } if (cacheKey != null && taskCache.containsKey(cacheKey)) { - return taskCache.get(cacheKey); + task = taskCache.get(cacheKey); + } + if (task != null) { + if (onCached != null) { + onCached.run(); + } + return task; } - LottieTask task = new LottieTask<>(callable); + task = new LottieTask<>(callable); if (cacheKey != null) { AtomicBoolean resultAlreadyCalled = new AtomicBoolean(false); task.addListener(result -> {