我在Github(https://github.com/alirezaeiii/Movies)中有一个示例,其中我有一个实用程序类来检查Internet网络连接:
class NetworkUtils(context: Context) : ConnectivityManager.NetworkCallback() {
private val networkLiveData: MutableLiveData<Boolean> = MutableLiveData()
private val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
fun getNetworkLiveData(): LiveData<Boolean> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
connectivityManager.registerDefaultNetworkCallback(this)
} else {
val builder = NetworkRequest.Builder()
connectivityManager.registerNetworkCallback(builder.build(), this)
}
var isConnected = false
connectivityManager.allNetworks.forEach { network ->
val networkCapability = connectivityManager.getNetworkCapabilities(network)
networkCapability?.let {
if (it.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
isConnected = true
return@forEach
}
}
}
networkLiveData.postValue(isConnected)
return networkLiveData
}
override fun onAvailable(network: Network) {
networkLiveData.postValue(true)
}
override fun onLost(network: Network) {
networkLiveData.postValue(false)
}
fun unRegister() {
connectivityManager.unregisterNetworkCallback(this)
}
}
在我在onCreate()和onDestroy()中观察到的unRegisterNetworkCallback活动中:
override fun onCreate() {
super.onCreate(savedInstanceState)
handleNetwork()
}
override fun onDestroy() {
super.onDestroy()
networkUtils.unRegister()
}
private fun handleNetwork() {
networkUtils.getNetworkLiveData().observe(this) { isConnected: Boolean ->
if (!isConnected) {
...
} else {
Log.d("Test", "Connected")
...
}
}
}
我第一次启动应用程序时,“已连接”标签将被调用一次,但当我旋转设备时,它将被调用两次。这是为什么?
我有另一个示例,其中我没有使用Navigation architecture component
,当我旋转时它被调用一次:https://github.com/alirezaeiii/TMDb-Paging/blob/master/app/src/main/java/com/sample/android/tmdb/ui/BaseActivity.kt
使用刀柄的供应商:
@Module
@InstallIn(SingletonComponent::class)
class AppUtilsModule {
@Singleton
@Provides
fun provideNetworkUtils(context: Context): NetworkUtils {
return NetworkUtils(context)
}
}
1条答案
按热度按时间i1icjdpr1#
由于这是单例。在首次创建活动并调用getNetworkLiveData之后,内部networkLiveData将填充值。在旋转之后,您将使用相同的NetworkUtils对象,该对象已将值存储在networkLiveData中,在注册期间,将返回现有的LiveData,但在返回之前,将有代码向其发布新值。
由于postValue是异步调用的,**在大多数情况下,**内部值的更改将在return语句之后调用。
最后,我们注册到livaData,它具有旧值,几毫秒后,我们收到新值。
有几个选项可以避免这种情况:
1.仅在新值与之前的值不同时发布新值(仍不完美)
1.返回实时数据时添加Transformations. distinctUntilChanged(networkLiveData)(仍不完善)
1.修改一些实用程序,并将与观察实时数据相关的逻辑和与从ConnectivityManager接收更新相关的日志分开
编辑:
在registerNetworkCallback之后还有另一个问题,回调是用当前状态调用的,所以再次更新了networkLiveData