7
7
8
8
package com .facebook .react .modules .network ;
9
9
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 ;
10
17
import android .os .Build ;
18
+ import android .os .Bundle ;
11
19
12
20
import com .facebook .common .logging .FLog ;
21
+ import com .facebook .react .ReactActivity ;
22
+ import com .facebook .react .bridge .ReactApplicationContext ;
13
23
14
24
import java .util .ArrayList ;
25
+ import java .util .Collections ;
15
26
import java .util .List ;
27
+ import java .util .Set ;
28
+ import java .util .WeakHashMap ;
16
29
import java .util .concurrent .TimeUnit ;
17
30
18
31
import javax .annotation .Nullable ;
@@ -33,6 +46,9 @@ public class OkHttpClientProvider {
33
46
// User-provided OkHttpClient factory
34
47
private static @ Nullable OkHttpClientFactory sFactory ;
35
48
49
+ private final static Set <OkHttpClient > sClients = Collections .newSetFromMap (
50
+ new WeakHashMap <OkHttpClient , Boolean >());
51
+
36
52
public static void setOkHttpClientFactory (OkHttpClientFactory factory ) {
37
53
sFactory = factory ;
38
54
}
@@ -43,6 +59,38 @@ public static OkHttpClient getOkHttpClient() {
43
59
}
44
60
return sClient ;
45
61
}
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
+ }
46
94
47
95
// okhttp3 OkHttpClient is immutable
48
96
// This allows app to init an OkHttpClient with custom settings.
@@ -51,10 +99,15 @@ public static void replaceOkHttpClient(OkHttpClient client) {
51
99
}
52
100
53
101
public static OkHttpClient createClient () {
102
+ OkHttpClient client ;
54
103
if (sFactory != null ) {
55
104
return sFactory .createNewNetworkModuleClient ();
56
105
}
57
- return createClientBuilder ().build ();
106
+ else {
107
+ client = createClientBuilder ().build ();
108
+ registerClientToEvictIdleConnectionsOnNetworkChange (client );
109
+ return client ;
110
+ }
58
111
}
59
112
60
113
public static OkHttpClient .Builder createClientBuilder () {
@@ -68,6 +121,10 @@ public static OkHttpClient.Builder createClientBuilder() {
68
121
return enableTls12OnPreLollipop (client );
69
122
}
70
123
124
+ public static void registerClientToEvictIdleConnectionsOnNetworkChange (OkHttpClient client ) {
125
+ sClients .add (client );
126
+ }
127
+
71
128
/*
72
129
On Android 4.1-4.4 (API level 16 to 19) TLS 1.1 and 1.2 are
73
130
available but not enabled by default. The following method
0 commit comments