mirror of
https://github.com/facebook/react-native.git
synced 2024-11-21 22:10:14 +00:00
feat(image): [android] adding force-cache
cache control option (#47426)
Summary: This PR follows up on https://github.com/facebook/react-native/issues/47182 and https://github.com/facebook/react-native/issues/47348 by adding `force-cache`, the final missing option to align caching controls with the existing behavior on iOS. Local caching behavior remains unchanged: if a cached image is available locally, it will be returned; otherwise, a network request will be made. When an image request is sent over the network, the `force-cache` option sent from the sent fJS side will now use the `okhttp3.CacheControl.FORCE_CACHE` directive. ## Changelog: [ANDROID] [ADDED] - Image `force-cache` caching control option Pull Request resolved: https://github.com/facebook/react-native/pull/47426 Test Plan: New example added to the RNTester under the cache policy examples. Then inspecting that the cache control is set correctly before sending it in the `okhttp3.Request` builder. ```kt FLog.w("ReactNative", "fetching uri: %s, with cacheControl: %s", uri, cacheControlBuilder.build().toString()) // fetching uri: https:...png?cacheBust=force-cache, with cacheControl: no-store, max-stale=2147483647, only-if-cached ``` This case was a bit more tricky to test in terms of e2e as it would involve some caching in the server as well, I'm open to suggestions to make this more complete. Reviewed By: javache Differential Revision: D65490360 Pulled By: Abbondanzo fbshipit-source-id: f807a9793f85caea39c59a370d057b9a1d450a78
This commit is contained in:
parent
c69e330324
commit
a0be88fd72
@ -50,8 +50,6 @@ export interface ImageURISource {
|
||||
* its age or expiration date. If there is no existing data in the cache corresponding
|
||||
* to a URL load request, no attempt is made to load the data from the originating source,
|
||||
* and the load is considered to have failed.
|
||||
*
|
||||
* @platform ios (for `force-cache`)
|
||||
*/
|
||||
cache?: 'default' | 'reload' | 'force-cache' | 'only-if-cached' | undefined;
|
||||
/**
|
||||
|
@ -65,8 +65,6 @@ export interface ImageURISource {
|
||||
* its age or expiration date. If there is no existing data in the cache corresponding
|
||||
* to a URL load request, no attempt is made to load the data from the originating source,
|
||||
* and the load is considered to have failed.
|
||||
*
|
||||
* @platform ios (for `force-cache`)
|
||||
*/
|
||||
+cache?: ?('default' | 'reload' | 'force-cache' | 'only-if-cached');
|
||||
|
||||
|
@ -3334,6 +3334,7 @@ public final class com/facebook/react/modules/fresco/FrescoModule$Companion {
|
||||
|
||||
public final class com/facebook/react/modules/fresco/ImageCacheControl : java/lang/Enum {
|
||||
public static final field DEFAULT Lcom/facebook/react/modules/fresco/ImageCacheControl;
|
||||
public static final field FORCE_CACHE Lcom/facebook/react/modules/fresco/ImageCacheControl;
|
||||
public static final field ONLY_IF_CACHED Lcom/facebook/react/modules/fresco/ImageCacheControl;
|
||||
public static final field RELOAD Lcom/facebook/react/modules/fresco/ImageCacheControl;
|
||||
public static fun getEntries ()Lkotlin/enums/EnumEntries;
|
||||
|
@ -15,6 +15,12 @@ public enum class ImageCacheControl {
|
||||
* be used to satisfy a URL load request.
|
||||
*/
|
||||
RELOAD,
|
||||
/**
|
||||
* The existing cache data will be used to satisfy a request, regardless of its age or expiration
|
||||
* date. If there is no existing data in the cache corresponding to a URL load request, the data
|
||||
* is loaded from the originating source.
|
||||
*/
|
||||
FORCE_CACHE,
|
||||
/**
|
||||
* The existing cache data will be used to satisfy a request, regardless of its age or expiration
|
||||
* date. If there is no existing data in the cache corresponding to a URL load request, no attempt
|
||||
|
@ -12,6 +12,7 @@ import com.facebook.imagepipeline.backends.okhttp3.OkHttpNetworkFetcher
|
||||
import com.facebook.imagepipeline.producers.NetworkFetcher
|
||||
import com.facebook.react.bridge.ReadableMap
|
||||
import com.facebook.react.modules.network.OkHttpCompat
|
||||
import java.util.concurrent.TimeUnit
|
||||
import okhttp3.CacheControl
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
@ -35,21 +36,26 @@ internal class ReactOkHttpNetworkFetcher(private val okHttpClient: OkHttpClient)
|
||||
fetchState.submitTime = SystemClock.elapsedRealtime()
|
||||
val uri = fetchState.uri
|
||||
var requestHeaders: Map<String, String>? = null
|
||||
val cacheControlBuilder = CacheControl.Builder().noStore()
|
||||
val cacheControlBuilder = CacheControl.Builder()
|
||||
if (fetchState.context.imageRequest is ReactNetworkImageRequest) {
|
||||
val networkImageRequest = fetchState.context.imageRequest as ReactNetworkImageRequest
|
||||
requestHeaders = getHeaders(networkImageRequest.headers)
|
||||
when (networkImageRequest.cacheControl) {
|
||||
ImageCacheControl.RELOAD -> {
|
||||
cacheControlBuilder.noCache()
|
||||
cacheControlBuilder.noStore().noCache()
|
||||
}
|
||||
ImageCacheControl.FORCE_CACHE -> {
|
||||
cacheControlBuilder.maxStale(Integer.MAX_VALUE, TimeUnit.SECONDS)
|
||||
}
|
||||
ImageCacheControl.ONLY_IF_CACHED -> {
|
||||
cacheControlBuilder.onlyIfCached()
|
||||
cacheControlBuilder.onlyIfCached().maxStale(Integer.MAX_VALUE, TimeUnit.SECONDS)
|
||||
}
|
||||
ImageCacheControl.DEFAULT -> {
|
||||
// No-op
|
||||
cacheControlBuilder.noStore()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cacheControlBuilder.noStore()
|
||||
}
|
||||
val headers = OkHttpCompat.getHeadersFromMap(requestHeaders)
|
||||
val request =
|
||||
|
@ -312,6 +312,7 @@ public class ReactImageView(
|
||||
null,
|
||||
"default" -> ImageCacheControl.DEFAULT
|
||||
"reload" -> ImageCacheControl.RELOAD
|
||||
"force-cache" -> ImageCacheControl.FORCE_CACHE
|
||||
"only-if-cached" -> ImageCacheControl.ONLY_IF_CACHED
|
||||
else -> ImageCacheControl.DEFAULT
|
||||
}
|
||||
|
@ -666,6 +666,18 @@ function CacheControlAndroidExample(): React.Node {
|
||||
key={reload}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.leftMargin}>
|
||||
<RNTesterText style={styles.resizeModeText}>Force-cache</RNTesterText>
|
||||
<Image
|
||||
source={{
|
||||
uri: fullImage.uri + '?cacheBust=force-cache',
|
||||
cache: 'force-cache',
|
||||
}}
|
||||
style={styles.base}
|
||||
key={reload}
|
||||
onError={e => console.log(e.nativeEvent.error)}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.leftMargin}>
|
||||
<RNTesterText style={styles.resizeModeText}>
|
||||
Only-if-cached
|
||||
|
Loading…
Reference in New Issue
Block a user