Fixed the stream was not closed when the lottie animation hit the cache (#2253)

This PR fixes the stream not closing when the lottie animation hits the cache.
diff --git a/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java b/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java
index 09c8c02..4f451fb 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 @@
    * <p>
    * This is particularly useful for animations loaded from the network. You can fetch the
    * bodymovin json from the network and pass it directly here.
+   * <p>
+   * 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 8532394..b74bcb1 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 @@
         LottieCompositionCache.getInstance().put(cacheKey, result.getValue());
       }
       return result;
-    });
+    }, null);
   }
 
   /**
@@ -184,7 +184,7 @@
   public static LottieTask<LottieComposition> 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 @@
       @Nullable Context originalContext = contextRef.get();
       Context context1 = originalContext != null ? originalContext : appContext;
       return fromRawResSync(context1, rawRes, cacheKey);
-    });
+    }, null);
   }
 
   /**
@@ -311,7 +311,7 @@
    * @see #fromJsonInputStreamSync(InputStream, String, boolean)
    */
   public static LottieTask<LottieComposition> 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 @@
     return cache(cacheKey, () -> {
       //noinspection deprecation
       return fromJsonSync(json, cacheKey);
-    });
+    }, null);
   }
 
   /**
@@ -361,7 +361,7 @@
    * @see #fromJsonStringSync(String, String)
    */
   public static LottieTask<LottieComposition> 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 LottieTask<LottieComposition> 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 @@
    * @see #fromZipStreamSync(Context, ZipInputStream, String)
    */
   public static LottieTask<LottieComposition> 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 @@
    * 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<LottieComposition> cache(
-      @Nullable final String cacheKey, Callable<LottieResult<LottieComposition>> callable) {
+  private static LottieTask<LottieComposition> cache(@Nullable final String cacheKey, Callable<LottieResult<LottieComposition>> callable,
+      @Nullable Runnable onCached) {
+    LottieTask<LottieComposition> 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<LottieComposition> task = new LottieTask<>(callable);
+    task = new LottieTask<>(callable);
     if (cacheKey != null) {
       AtomicBoolean resultAlreadyCalled = new AtomicBoolean(false);
       task.addListener(result -> {