Skip to content

Commit 6b35cbb

Browse files
committed
Offload connectivity monitor to a background thread
Change-Id: I9a2ef7766ae6abc6d8a7c86a4b49ef3c795e446c
1 parent 88c3eb0 commit 6b35cbb

File tree

1 file changed

+43
-29
lines changed

1 file changed

+43
-29
lines changed

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

Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -26,57 +26,71 @@ 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 androidx.tracing.trace
31+
import com.google.samples.apps.nowinandroid.core.network.Dispatcher
32+
import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO
2933
import dagger.hilt.android.qualifiers.ApplicationContext
34+
import kotlinx.coroutines.CoroutineDispatcher
3035
import kotlinx.coroutines.channels.awaitClose
3136
import kotlinx.coroutines.flow.Flow
3237
import kotlinx.coroutines.flow.callbackFlow
3338
import kotlinx.coroutines.flow.conflate
39+
import kotlinx.coroutines.flow.flowOn
3440
import javax.inject.Inject
3541

3642
internal class ConnectivityManagerNetworkMonitor @Inject constructor(
3743
@ApplicationContext private val context: Context,
44+
@Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher,
3845
) : NetworkMonitor {
3946
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-
}
47+
trace("NetworkMonitor.callbackFlow") {
48+
val connectivityManager = context.getSystemService<ConnectivityManager>()
49+
if (connectivityManager == null) {
50+
channel.trySend(false)
51+
channel.close()
52+
return@callbackFlow
53+
}
54+
55+
/**
56+
* The callback's methods are invoked on changes to *any* network matching the [NetworkRequest],
57+
* not just the active network. So we can simply track the presence (or absence) of such [Network].
58+
*/
59+
val callback = object : NetworkCallback() {
4660

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() {
61+
private val networks = mutableSetOf<Network>()
5262

53-
private val networks = mutableSetOf<Network>()
63+
override fun onAvailable(network: Network) {
64+
networks += network
65+
channel.trySend(true)
66+
}
5467

55-
override fun onAvailable(network: Network) {
56-
networks += network
57-
channel.trySend(true)
68+
override fun onLost(network: Network) {
69+
networks -= network
70+
channel.trySend(networks.isNotEmpty())
71+
}
5872
}
5973

60-
override fun onLost(network: Network) {
61-
networks -= network
62-
channel.trySend(networks.isNotEmpty())
74+
trace("NetworkMonitor.registerNetworkCallback") {
75+
val request = Builder()
76+
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
77+
.build()
78+
connectivityManager.registerNetworkCallback(request, callback)
6379
}
64-
}
6580

66-
val request = Builder()
67-
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
68-
.build()
69-
connectivityManager.registerNetworkCallback(request, callback)
81+
/**
82+
* Sends the latest connectivity status to the underlying channel.
83+
*/
84+
channel.trySend(connectivityManager.isCurrentlyConnected())
7085

71-
/**
72-
* Sends the latest connectivity status to the underlying channel.
73-
*/
74-
channel.trySend(connectivityManager.isCurrentlyConnected())
86+
Trace.endSection()
7587

76-
awaitClose {
77-
connectivityManager.unregisterNetworkCallback(callback)
88+
awaitClose {
89+
connectivityManager.unregisterNetworkCallback(callback)
90+
}
7891
}
7992
}
93+
.flowOn(ioDispatcher)
8094
.conflate()
8195

8296
@Suppress("DEPRECATION")

0 commit comments

Comments
 (0)