37
37
import io .grpc .internal .GrpcUtil ;
38
38
import java .util .concurrent .TimeUnit ;
39
39
import javax .annotation .Nullable ;
40
+ import javax .annotation .concurrent .GuardedBy ;
40
41
41
42
/**
42
43
* Builds a {@link ManagedChannel} that, when provided with a {@link Context}, will automatically
@@ -120,8 +121,8 @@ static final class AndroidChannel extends ManagedChannel {
120
121
121
122
private final Object lock = new Object ();
122
123
123
- // May only go from true to false, and lock must be held when assigning this
124
- private volatile boolean needToUnregisterListener ;
124
+ @ GuardedBy ( " lock" )
125
+ private Runnable unregisterRunnable ;
125
126
126
127
@ VisibleForTesting
127
128
AndroidChannel (final ManagedChannel delegate , @ Nullable Context context ) {
@@ -132,12 +133,12 @@ static final class AndroidChannel extends ManagedChannel {
132
133
connectivityManager =
133
134
(ConnectivityManager ) context .getSystemService (Context .CONNECTIVITY_SERVICE );
134
135
configureNetworkMonitoring ();
135
- needToUnregisterListener = true ;
136
136
} else {
137
137
connectivityManager = null ;
138
138
}
139
139
}
140
140
141
+ @ GuardedBy ("lock" )
141
142
private void configureNetworkMonitoring () {
142
143
// Android N added the registerDefaultNetworkCallback API to listen to changes in the device's
143
144
// default network. For earlier Android API levels, use the BroadcastReceiver API.
@@ -151,25 +152,37 @@ private void configureNetworkMonitoring() {
151
152
152
153
defaultNetworkCallback = new DefaultNetworkCallback (isConnected );
153
154
connectivityManager .registerDefaultNetworkCallback (defaultNetworkCallback );
155
+ unregisterRunnable =
156
+ new Runnable () {
157
+ @ TargetApi (Build .VERSION_CODES .LOLLIPOP )
158
+ @ Override
159
+ public void run () {
160
+ connectivityManager .unregisterNetworkCallback (defaultNetworkCallback );
161
+ defaultNetworkCallback = null ;
162
+ }
163
+ };
154
164
} else {
155
165
networkReceiver = new NetworkReceiver ();
156
166
IntentFilter networkIntentFilter =
157
167
new IntentFilter (ConnectivityManager .CONNECTIVITY_ACTION );
158
168
context .registerReceiver (networkReceiver , networkIntentFilter );
169
+ unregisterRunnable =
170
+ new Runnable () {
171
+ @ TargetApi (Build .VERSION_CODES .LOLLIPOP )
172
+ @ Override
173
+ public void run () {
174
+ context .unregisterReceiver (networkReceiver );
175
+ networkReceiver = null ;
176
+ }
177
+ };
159
178
}
160
179
}
161
180
162
181
private void unregisterNetworkListener () {
163
- if (needToUnregisterListener ) {
164
- synchronized (lock ) {
165
- if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .N && connectivityManager != null ) {
166
- connectivityManager .unregisterNetworkCallback (defaultNetworkCallback );
167
- defaultNetworkCallback = null ;
168
- } else {
169
- context .unregisterReceiver (networkReceiver );
170
- networkReceiver = null ;
171
- }
172
- needToUnregisterListener = false ;
182
+ synchronized (lock ) {
183
+ if (unregisterRunnable != null ) {
184
+ unregisterRunnable .run ();
185
+ unregisterRunnable = null ;
173
186
}
174
187
}
175
188
}
0 commit comments