Skip to content

Commit 5a267f6

Browse files
committed
networking: Fix requests failing when turning network off and on facebook#19709.
This bug is probably actually a bug in OkHttp: square/okhttp#4079 Both issues linked above contain extensive details about the issue, its likely origins and how to reproduce it. A short summary of the issue and the fix in this commit: On Android, disconnecting from the network somehow corrupts the idle connections in okhttp clients. New requests made over these clients fail. This commit works around that bug by clearing the idle connection pool of each client when Android disconnects from the network.
1 parent 370bcff commit 5a267f6

File tree

2 files changed

+53
-2
lines changed

2 files changed

+53
-2
lines changed

ReactAndroid/src/main/java/com/facebook/react/ReactActivity.java

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
1818
import com.facebook.react.modules.core.PermissionAwareActivity;
1919
import com.facebook.react.modules.core.PermissionListener;
20+
import com.facebook.react.modules.network.OkHttpClientProvider;
2021

2122
/**
2223
* Base Activity for React Native applications.
@@ -50,6 +51,7 @@ protected ReactActivityDelegate createReactActivityDelegate() {
5051
protected void onCreate(Bundle savedInstanceState) {
5152
super.onCreate(savedInstanceState);
5253
mDelegate.onCreate(savedInstanceState);
54+
OkHttpClientProvider.addNetworkListenerToEvictClientConnectionsOnDisconnect(getApplicationContext());
5355
}
5456

5557
@Override

ReactAndroid/src/main/java/com/facebook/react/modules/network/OkHttpClientProvider.java

+51-2
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,25 @@
77

88
package 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;
1017
import android.os.Build;
18+
import android.os.Bundle;
1119

1220
import com.facebook.common.logging.FLog;
21+
import com.facebook.react.ReactActivity;
22+
import com.facebook.react.bridge.ReactApplicationContext;
1323

1424
import java.util.ArrayList;
25+
import java.util.Collections;
1526
import java.util.List;
27+
import java.util.Set;
28+
import java.util.WeakHashMap;
1629
import java.util.concurrent.TimeUnit;
1730

1831
import javax.annotation.Nullable;
@@ -33,6 +46,9 @@ public class OkHttpClientProvider {
3346
// User-provided OkHttpClient factory
3447
private static @Nullable OkHttpClientFactory sFactory;
3548

49+
private static Set<OkHttpClient> sClients = Collections.newSetFromMap(
50+
new WeakHashMap<OkHttpClient, Boolean>());
51+
3652
public static void setOkHttpClientFactory(OkHttpClientFactory factory) {
3753
sFactory = factory;
3854
}
@@ -43,18 +59,51 @@ 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+
public static void addNetworkListenerToEvictClientConnectionsOnDisconnect(Context context) {
74+
BroadcastReceiver br = new BroadcastReceiver() {
75+
@Override
76+
public void onReceive(Context context, Intent intent) {
77+
Bundle extras = intent.getExtras();
78+
NetworkInfo info = extras.getParcelable("networkInfo");
79+
NetworkInfo.State state = info.getState();
80+
if (state == NetworkInfo.State.DISCONNECTED) {
81+
new EvictIdleConnectionsTask().execute();
82+
}
83+
}
84+
};
85+
final IntentFilter intentFilter = new IntentFilter();
86+
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
87+
context.registerReceiver(br, intentFilter);
88+
}
4689

4790
// okhttp3 OkHttpClient is immutable
4891
// This allows app to init an OkHttpClient with custom settings.
4992
public static void replaceOkHttpClient(OkHttpClient client) {
5093
sClient = client;
94+
sClients.add(client);
5195
}
5296

5397
public static OkHttpClient createClient() {
98+
OkHttpClient client;
5499
if (sFactory != null) {
55-
return sFactory.createNewNetworkModuleClient();
100+
client = sFactory.createNewNetworkModuleClient();
56101
}
57-
return createClientBuilder().build();
102+
else {
103+
client = createClientBuilder().build();
104+
}
105+
sClients.add(client);
106+
return client;
58107
}
59108

60109
public static OkHttpClient.Builder createClientBuilder() {

0 commit comments

Comments
 (0)