Skip to content

Commit 7f2ce57

Browse files
authored
Merge pull request #1368 from android/mlykotom/offload-connectivity-monitor
Offload connectivity monitor to a background thread
2 parents 3dd4240 + c396352 commit 7f2ce57

File tree

1 file changed

+41
-30
lines changed

1 file changed

+41
-30
lines changed

core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/ConnectivityManagerNetworkMonitor.kt

+41-30
Original file line numberDiff line numberDiff line change
@@ -26,57 +26,68 @@ import android.net.NetworkRequest.Builder
2626
import android.os.Build.VERSION
2727
import android.os.Build.VERSION_CODES
2828
import androidx.core.content.getSystemService
29+
import androidx.tracing.trace
30+
import com.google.samples.apps.nowinandroid.core.network.Dispatcher
31+
import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO
2932
import dagger.hilt.android.qualifiers.ApplicationContext
33+
import kotlinx.coroutines.CoroutineDispatcher
3034
import kotlinx.coroutines.channels.awaitClose
3135
import kotlinx.coroutines.flow.Flow
3236
import kotlinx.coroutines.flow.callbackFlow
3337
import kotlinx.coroutines.flow.conflate
38+
import kotlinx.coroutines.flow.flowOn
3439
import javax.inject.Inject
3540

3641
internal class ConnectivityManagerNetworkMonitor @Inject constructor(
3742
@ApplicationContext private val context: Context,
43+
@Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher,
3844
) : NetworkMonitor {
3945
override val isOnline: Flow<Boolean> = callbackFlow {
40-
val connectivityManager = context.getSystemService<ConnectivityManager>()
41-
if (connectivityManager == null) {
42-
channel.trySend(false)
43-
channel.close()
44-
return@callbackFlow
45-
}
46+
trace("NetworkMonitor.callbackFlow") {
47+
val connectivityManager = context.getSystemService<ConnectivityManager>()
48+
if (connectivityManager == null) {
49+
channel.trySend(false)
50+
channel.close()
51+
return@callbackFlow
52+
}
4653

47-
/**
48-
* The callback's methods are invoked on changes to *any* network matching the [NetworkRequest],
49-
* not just the active network. So we can simply track the presence (or absence) of such [Network].
50-
*/
51-
val callback = object : NetworkCallback() {
54+
/**
55+
* The callback's methods are invoked on changes to *any* network matching the [NetworkRequest],
56+
* not just the active network. So we can simply track the presence (or absence) of such [Network].
57+
*/
58+
val callback = object : NetworkCallback() {
5259

53-
private val networks = mutableSetOf<Network>()
60+
private val networks = mutableSetOf<Network>()
5461

55-
override fun onAvailable(network: Network) {
56-
networks += network
57-
channel.trySend(true)
58-
}
62+
override fun onAvailable(network: Network) {
63+
networks += network
64+
channel.trySend(true)
65+
}
5966

60-
override fun onLost(network: Network) {
61-
networks -= network
62-
channel.trySend(networks.isNotEmpty())
67+
override fun onLost(network: Network) {
68+
networks -= network
69+
channel.trySend(networks.isNotEmpty())
70+
}
6371
}
64-
}
6572

66-
val request = Builder()
67-
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
68-
.build()
69-
connectivityManager.registerNetworkCallback(request, callback)
73+
trace("NetworkMonitor.registerNetworkCallback") {
74+
val request = Builder()
75+
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
76+
.build()
77+
connectivityManager.registerNetworkCallback(request, callback)
78+
}
7079

71-
/**
72-
* Sends the latest connectivity status to the underlying channel.
73-
*/
74-
channel.trySend(connectivityManager.isCurrentlyConnected())
80+
/**
81+
* Sends the latest connectivity status to the underlying channel.
82+
*/
83+
channel.trySend(connectivityManager.isCurrentlyConnected())
7584

76-
awaitClose {
77-
connectivityManager.unregisterNetworkCallback(callback)
85+
awaitClose {
86+
connectivityManager.unregisterNetworkCallback(callback)
87+
}
7888
}
7989
}
90+
.flowOn(ioDispatcher)
8091
.conflate()
8192

8293
@Suppress("DEPRECATION")

0 commit comments

Comments
 (0)