Skip to content

Commit

Permalink
Add HTTP cache by default (like iOS) (#18348)
Browse files Browse the repository at this point in the history
Summary:
<!--
Thank you for sending the PR! We appreciate you spending the time to work on these changes.

Help us understand your motivation by explaining why you decided to make this change.

You can learn more about contributing to React Native here: http://facebook.github.io/react-native/docs/contributing.html

Happy contributing!

-->

On iOS, the cache is enabled by default but it's not the case on Android. This PR adds 10Mo of HTTP cache by default. 10Mo was chosen arbitrarily.

Fixes #16795

<!--(Write your test plan here. If you changed any code, please provide us with clear instructions on how you verified your changes work. Bonus points for screenshots and videos!)-->

I wrote it so there's no breaking change for those already using the `OkHttpClientProvider.createClient` and `OkHttpClientProvider.createClientBuilder` public methods.

1. react-native init TestAndroidCache
2. Followed https://facebook.github.io/react-native/docs/android-building-from-source.html to build  with this branch as react-native
3. Added the following code in the App.js (with correct URL_WITH_CACHE_CONTROL)
4. Made sure the debugger is closed
5. Throttled my mac's network speed with the `Network link conditioner` (edge)
6. Tapped "Fetch", it shows ~4000
7. Tapped "Fetch" again, it shows ~6

```js
import React, { Component } from 'react';
import {
  StyleSheet,
  Alert,
  View,
  Button
} from 'react-native';

type Props = {};
export default class App extends Component<Props> {
  fetch = () => {
    const start = Date.now();
    fetch('{URL_WITH_CACHE_CONTROL}').then(() => {
      const diff = Date.now() - start;
      Alert.alert(diff.toString());
    });
  };

  render() {
    return (
      <View style={styles.container}>
        <Button title={"fetch"} onPress={this.fetch} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
});
```

None

<!--
Help reviewers and the release process by writing your own release notes

**INTERNAL and MINOR tagged notes will not be included in the next version's final release notes.**

  CATEGORY
[----------]        TYPE
[ CLI      ]   [-------------]      LOCATION
[ DOCS     ]   [ BREAKING    ]   [-------------]
[ GENERAL  ]   [ BUGFIX      ]   [-{Component}-]
[ INTERNAL ]   [ ENHANCEMENT ]   [ {File}      ]
[ IOS      ]   [ FEATURE     ]   [ {Directory} ]   |-----------|
[ ANDROID  ]   [ MINOR       ]   [ {Framework} ] - | {Message} |
[----------]   [-------------]   [-------------]   |-----------|

[CATEGORY] [TYPE] [LOCATION] - MESSAGE

 EXAMPLES:

 [IOS] [BREAKING] [FlatList] - Change a thing that breaks other things
 [ANDROID] [BUGFIX] [TextInput] - Did a thing to TextInput
 [CLI] [FEATURE] [local-cli/info/info.js] - CLI easier to do things with
 [DOCS] [BUGFIX] [GettingStarted.md] - Accidentally a thing/word
 [GENERAL] [ENHANCEMENT] [Yoga] - Added new yoga thing/position
 [INTERNAL] [FEATURE] [./scripts] - Added thing to script that nobody will see
-->
[ANDROID] [FEATURE] [Networking] Add HTTP caching
Pull Request resolved: #18348

Differential Revision: D13680430

Pulled By: hramos

fbshipit-source-id: 1e49cf75702db72b20a316e9cdd971605f8fe7e0
  • Loading branch information
Minishlink authored and facebook-github-bot committed Jan 17, 2019
1 parent 091edd2 commit cf85d0e
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ public interface ResponseHandler {
* @param context the ReactContext of the application
*/
public NetworkingModule(final ReactApplicationContext context) {
this(context, null, OkHttpClientProvider.createClient(), null);
this(context, null, OkHttpClientProvider.createClient(context), null);
}

/**
Expand All @@ -174,7 +174,7 @@ public NetworkingModule(final ReactApplicationContext context) {
public NetworkingModule(
ReactApplicationContext context,
List<NetworkInterceptorCreator> networkInterceptorCreators) {
this(context, null, OkHttpClientProvider.createClient(), networkInterceptorCreators);
this(context, null, OkHttpClientProvider.createClient(context), networkInterceptorCreators);
}

/**
Expand All @@ -183,7 +183,7 @@ public NetworkingModule(
* caller does not provide one explicitly
*/
public NetworkingModule(ReactApplicationContext context, String defaultUserAgent) {
this(context, defaultUserAgent, OkHttpClientProvider.createClient(), null);
this(context, defaultUserAgent, OkHttpClientProvider.createClient(context), null);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,19 @@

package com.facebook.react.modules.network;

import android.content.Context;
import android.os.Build;

import com.facebook.common.logging.FLog;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.annotation.Nullable;

import okhttp3.Cache;
import okhttp3.ConnectionSpec;
import okhttp3.OkHttpClient;
import okhttp3.TlsVersion;
Expand Down Expand Up @@ -57,6 +60,13 @@ public static OkHttpClient createClient() {
return createClientBuilder().build();
}

public static OkHttpClient createClient(Context context) {
if (sFactory != null) {
return sFactory.createNewNetworkModuleClient();
}
return createClientBuilder(context).build();
}

public static OkHttpClient.Builder createClientBuilder() {
// No timeouts by default
OkHttpClient.Builder client = new OkHttpClient.Builder()
Expand All @@ -68,6 +78,24 @@ public static OkHttpClient.Builder createClientBuilder() {
return enableTls12OnPreLollipop(client);
}

public static OkHttpClient.Builder createClientBuilder(Context context) {
int cacheSize = 10 * 1024 * 1024; // 10 Mo
return createClientBuilder(context, cacheSize);
}

public static OkHttpClient.Builder createClientBuilder(Context context, int cacheSize) {
OkHttpClient.Builder client = createClientBuilder();

if (cacheSize == 0) {
return client;
}

File cacheDirectory = new File(context.getCacheDir(), "http-cache");
Cache cache = new Cache(cacheDirectory, cacheSize);

return client.cache(cache);
}

/*
On Android 4.1-4.4 (API level 16 to 19) TLS 1.1 and 1.2 are
available but not enabled by default. The following method
Expand Down

0 comments on commit cf85d0e

Please sign in to comment.