NetworkViewModel: Move back as provider class with changes

* Keeping it as viewmodel makes it leak memory
* Register callbacks for default network, ignore old Android versions
* Simplify the logic and make it a flow

Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
Aayush Gupta
2024-11-09 21:53:09 +05:30
parent b6416cdaf7
commit 87d821490d
4 changed files with 95 additions and 104 deletions

View File

@@ -24,7 +24,6 @@ import android.os.Bundle
import android.view.View
import androidx.activity.addCallback
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat.Type.displayCutout
@@ -34,6 +33,7 @@ import androidx.lifecycle.lifecycleScope
import androidx.navigation.FloatingWindow
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.setupWithNavController
import com.aurora.extensions.isNAndAbove
import com.aurora.store.data.helper.UpdateHelper
import com.aurora.store.data.model.NetworkStatus
import com.aurora.store.data.receiver.MigrationReceiver
@@ -41,19 +41,23 @@ import com.aurora.store.databinding.ActivityMainBinding
import com.aurora.store.util.Preferences
import com.aurora.store.util.Preferences.PREFERENCE_DEFAULT_SELECTED_TAB
import com.aurora.store.view.ui.sheets.NetworkDialogSheet
import com.aurora.store.viewmodel.network.NetworkViewModel
import com.aurora.store.data.providers.NetworkProvider
import com.aurora.store.util.PackageUtil
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import javax.inject.Inject
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject
lateinit var updateHelper: UpdateHelper
lateinit var networkProvider: NetworkProvider
private val networkViewModel: NetworkViewModel by viewModels()
@Inject
lateinit var updateHelper: UpdateHelper
private lateinit var B: ActivityMainBinding
@@ -86,31 +90,31 @@ class MainActivity : AppCompatActivity() {
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
networkViewModel.register()
networkViewModel.status.observe(this) { networkStatus ->
when (networkStatus) {
NetworkStatus.AVAILABLE -> {
if (!supportFragmentManager.isDestroyed && isIntroDone()) {
val fragment = supportFragmentManager
.findFragmentByTag(NetworkDialogSheet.TAG)
fragment?.let {
if (isNAndAbove && !PackageUtil.isTv(this)) {
networkProvider.status.onEach { networkStatus ->
when (networkStatus) {
NetworkStatus.AVAILABLE -> {
if (!supportFragmentManager.isDestroyed && isIntroDone()) {
val fragment = supportFragmentManager
.findFragmentByTag(NetworkDialogSheet.TAG)
fragment?.let {
supportFragmentManager.beginTransaction()
.remove(fragment)
.commitAllowingStateLoss()
}
}
}
NetworkStatus.UNAVAILABLE -> {
if (!supportFragmentManager.isDestroyed && isIntroDone()) {
supportFragmentManager.beginTransaction()
.remove(fragment)
.add(NetworkDialogSheet.newInstance(), NetworkDialogSheet.TAG)
.commitAllowingStateLoss()
}
}
}
NetworkStatus.LOST -> {
if (!supportFragmentManager.isDestroyed && isIntroDone()) {
supportFragmentManager.beginTransaction()
.add(NetworkDialogSheet.newInstance(), NetworkDialogSheet.TAG)
.commitAllowingStateLoss()
}
}
else -> {}
}
}.launchIn(AuroraApp.scope)
}
B.navView.setupWithNavController(navController)
@@ -157,11 +161,6 @@ class MainActivity : AppCompatActivity() {
}
}
override fun onDestroy() {
networkViewModel.unregister()
super.onDestroy()
}
private fun isIntroDone(): Boolean {
return Preferences.getBoolean(this@MainActivity, Preferences.PREFERENCE_INTRO)
}

View File

@@ -2,6 +2,5 @@ package com.aurora.store.data.model
enum class NetworkStatus {
AVAILABLE,
UNAVAILABLE,
LOST
UNAVAILABLE
}

View File

@@ -0,0 +1,66 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.data.providers
import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.core.content.getSystemService
import com.aurora.store.data.model.NetworkStatus
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
import javax.inject.Singleton
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch
/**
* A simple provider with a flow to observe internet connectivity changes
*/
@Singleton
class NetworkProvider @Inject constructor(@ApplicationContext private val context: Context) {
private val connectivityManager = context.getSystemService<ConnectivityManager>()!!
@get:RequiresApi(Build.VERSION_CODES.N)
val status: Flow<NetworkStatus>
get() {
return callbackFlow {
val networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
super.onAvailable(network)
launch { send(NetworkStatus.AVAILABLE) }
}
override fun onLost(network: Network) {
super.onLost(network)
launch { send(NetworkStatus.UNAVAILABLE) }
}
}
connectivityManager.registerDefaultNetworkCallback(networkCallback)
awaitClose { connectivityManager.unregisterNetworkCallback(networkCallback) }
}.distinctUntilChanged()
}
}

View File

@@ -1,73 +0,0 @@
/*
* Aurora Store
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
*
* Aurora Store is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Aurora Store is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.aurora.store.viewmodel.network
import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import androidx.core.content.getSystemService
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.aurora.extensions.isMAndAbove
import com.aurora.store.data.model.NetworkStatus
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
@HiltViewModel
class NetworkViewModel @Inject constructor(
@ApplicationContext private val context: Context
) : ViewModel() {
val status: MutableLiveData<NetworkStatus> = MutableLiveData(NetworkStatus.UNAVAILABLE)
private val connectivityManager = context.getSystemService<ConnectivityManager>()
private val networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
super.onAvailable(network)
status.postValue(NetworkStatus.AVAILABLE)
}
override fun onLost(network: Network) {
super.onLost(network)
status.postValue(NetworkStatus.LOST)
}
}
fun register() {
connectivityManager?.registerNetworkCallback(getNetworkRequest(), networkCallback)
}
fun unregister() {
connectivityManager?.unregisterNetworkCallback(networkCallback)
}
private fun getNetworkRequest(): NetworkRequest {
val networkRequest = NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
if (isMAndAbove) {
networkRequest.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
}
return networkRequest.build()
}
}