diff --git a/Libraries/Image/Image.android.js b/Libraries/Image/Image.android.js index ae2c8d5ef..4eff9533e 100644 --- a/Libraries/Image/Image.android.js +++ b/Libraries/Image/Image.android.js @@ -185,6 +185,17 @@ var Image = React.createClass({ abortPrefetch(requestId: number) { ImageLoader.abortRequest(requestId); }, + + /** + * Perform cache interrogation. + * + * @param urls the list of image URLs to check the cache for. + * @return a mapping from url to cache status, such as "disk" or "memory". If a requested URL is + * not in the mapping, it means it's not in the cache. + */ + async queryCache(urls: Array): Promise> { + return await ImageLoader.queryCache(urls); + } }, mixins: [NativeMethodsMixin], diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/image/ImageLoaderModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/image/ImageLoaderModule.java index 54730146d..b717969e1 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/image/ImageLoaderModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/image/ImageLoaderModule.java @@ -20,15 +20,18 @@ import com.facebook.datasource.BaseDataSubscriber; import com.facebook.datasource.DataSource; import com.facebook.datasource.DataSubscriber; import com.facebook.drawee.backends.pipeline.Fresco; +import com.facebook.imagepipeline.core.ImagePipeline; import com.facebook.imagepipeline.image.CloseableImage; import com.facebook.imagepipeline.request.ImageRequest; import com.facebook.imagepipeline.request.ImageRequestBuilder; import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.GuardedAsyncTask; import com.facebook.react.bridge.LifecycleEventListener; import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.WritableMap; public class ImageLoaderModule extends ReactContextBaseJavaModule implements @@ -175,6 +178,28 @@ public class ImageLoaderModule extends ReactContextBaseJavaModule implements } } + @ReactMethod + public void queryCache(final ReadableArray uris, final Promise promise) { + // perform cache interrogation in async task as disk cache checks are expensive + new GuardedAsyncTask(getReactApplicationContext()) { + @Override + protected void doInBackgroundGuarded(Void... params) { + WritableMap result = Arguments.createMap(); + ImagePipeline imagePipeline = Fresco.getImagePipeline(); + for (int i = 0; i < uris.size(); i++) { + String uriString = uris.getString(i); + final Uri uri = Uri.parse(uriString); + if (imagePipeline.isInBitmapMemoryCache(uri)) { + result.putString(uriString, "memory"); + } else if (imagePipeline.isInDiskCacheSync(uri)) { + result.putString(uriString, "disk"); + } + } + promise.resolve(result); + } + }.executeOnExecutor(GuardedAsyncTask.THREAD_POOL_EXECUTOR); + } + private void registerRequest(int requestId, DataSource request) { synchronized (mEnqueuedRequestMonitor) { mEnqueuedRequests.put(requestId, request);