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.
@@ -54,7 +102,11 @@ public static OkHttpClient createClient() {
54
102
if (sFactory != null ) {
55
103
return sFactory .createNewNetworkModuleClient ();
56
104
}
57
- return createClientBuilder ().build ();
105
+ else {
106
+ final OkHttpClient client = createClientBuilder ().build ();
107
+ registerClientToEvictIdleConnectionsOnNetworkChange (client );
108
+ return client ;
109
+ }
58
110
}
59
111
60
112
public static OkHttpClient .Builder createClientBuilder () {
@@ -68,6 +120,10 @@ public static OkHttpClient.Builder createClientBuilder() {
68
120
return enableTls12OnPreLollipop (client );
69
121
}
70
122
123
+ public static void registerClientToEvictIdleConnectionsOnNetworkChange (OkHttpClient client ) {
124
+ sClients .add (client );
125
+ }
126
+
71
127
/*
72
128
On Android 4.1-4.4 (API level 16 to 19) TLS 1.1 and 1.2 are
73
129
available but not enabled by default. The following method
0 commit comments