77
88package com .facebook .react .modules .network ;
99
10+ import android .content .BroadcastReceiver ;
11+ import android .content .Context ;
12+ import android .content .Intent ;
13+ import android .content .IntentFilter ;
14+ import android .net .ConnectivityManager ;
15+ import android .net .NetworkInfo ;
16+ import android .os .AsyncTask ;
1017import android .os .Build ;
18+ import android .os .Bundle ;
1119
1220import com .facebook .common .logging .FLog ;
21+ import com .facebook .react .ReactActivity ;
22+ import com .facebook .react .bridge .ReactApplicationContext ;
1323
1424import java .util .ArrayList ;
25+ import java .util .Collections ;
1526import java .util .List ;
27+ import java .util .Set ;
28+ import java .util .WeakHashMap ;
1629import java .util .concurrent .TimeUnit ;
1730
1831import javax .annotation .Nullable ;
@@ -33,6 +46,9 @@ public class OkHttpClientProvider {
3346 // User-provided OkHttpClient factory
3447 private static @ Nullable OkHttpClientFactory sFactory ;
3548
49+ private final static Set <OkHttpClient > sClients = Collections .newSetFromMap (
50+ new WeakHashMap <OkHttpClient , Boolean >());
51+
3652 public static void setOkHttpClientFactory (OkHttpClientFactory factory ) {
3753 sFactory = factory ;
3854 }
@@ -43,6 +59,38 @@ public static OkHttpClient getOkHttpClient() {
4359 }
4460 return sClient ;
4561 }
62+
63+ private static class EvictIdleConnectionsTask extends AsyncTask {
64+ @ Override
65+ protected Object doInBackground (Object [] objects ) {
66+ for (OkHttpClient client : sClients ) {
67+ client .connectionPool ().evictAll ();
68+ }
69+ return null ;
70+ }
71+ }
72+
73+ /*
74+ See https://github.com/facebook/react-native/issues/19709 for context.
75+ We know that idle connections get corrupted when the connectivity state
76+ changes to disconnected, but the debugging of this issue hasn't been
77+ exhaustive and it's possible that other changes in connectivity also
78+ corrupt idle connections. `CONNECTIVITY_ACTION`s occur infrequently
79+ enough to go safe and evict all idle connections on every such action.
80+ */
81+ public static void addNetworkListenerToEvictIdleConnectionsOnNetworkChange (Context context ) {
82+ final BroadcastReceiver br = new BroadcastReceiver () {
83+ @ Override
84+ public void onReceive (Context context , Intent intent ) {
85+ if (intent .getAction ().equals (ConnectivityManager .CONNECTIVITY_ACTION )) {
86+ new EvictIdleConnectionsTask ().execute ();
87+ }
88+ }
89+ };
90+ final IntentFilter intentFilter = new IntentFilter ();
91+ intentFilter .addAction (ConnectivityManager .CONNECTIVITY_ACTION );
92+ context .registerReceiver (br , intentFilter );
93+ }
4694
4795 // okhttp3 OkHttpClient is immutable
4896 // This allows app to init an OkHttpClient with custom settings.
@@ -51,10 +99,15 @@ public static void replaceOkHttpClient(OkHttpClient client) {
5199 }
52100
53101 public static OkHttpClient createClient () {
102+ OkHttpClient client ;
54103 if (sFactory != null ) {
55104 return sFactory .createNewNetworkModuleClient ();
56105 }
57- return createClientBuilder ().build ();
106+ else {
107+ client = createClientBuilder ().build ();
108+ registerClientToEvictIdleConnectionsOnNetworkChange (client );
109+ return client ;
110+ }
58111 }
59112
60113 public static OkHttpClient .Builder createClientBuilder () {
@@ -68,6 +121,10 @@ public static OkHttpClient.Builder createClientBuilder() {
68121 return enableTls12OnPreLollipop (client );
69122 }
70123
124+ public static void registerClientToEvictIdleConnectionsOnNetworkChange (OkHttpClient client ) {
125+ sClients .add (client );
126+ }
127+
71128 /*
72129 On Android 4.1-4.4 (API level 16 to 19) TLS 1.1 and 1.2 are
73130 available but not enabled by default. The following method
0 commit comments