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