When working on large Android projects, network reliability is a key concern. The NetworkStateObserver library simplifies network state monitoring and provides a clean way to handle connectivity issues.
In this article, we’ll explore how to integrate NetworkStateObserver into a large project by creating an abstract base activity class. We’ll then demonstrate how to use this base class in individual activities. Finally, I’ll share some tips for leveraging the library efficiently.
Link to the library on GitHub
Why Use NetworkStateObserver?
The NetworkStateObserver library:
- Monitors network changes in real-time.
- Provides granular network states (“Available”, “Unavailable”, etc.).
- Simplifies handling of reconnection logic.
- Can be integrated into existing projects with minimal effort.
Step 1: Add the Library to Your Project
Include NetworkStateObserver in your build.gradle file:
implementation 'io.github.rhymezxcode:networkstateobserver:1.1.3'
Sync your project to download the library.
Step 2: Create an Abstract BaseActivity
The BaseActivity will serve as a parent class for all your activities. It encapsulates common network-related behavior, reducing redundancy and ensuring consistent behavior across the app.
package com.example.app.base
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import io.github.rhymezxcode.networkstateobserver.network.NetworkObserver
import io.github.rhymezxcode.networkstateobserver.network.NetworkStateObserver
import io.github.rhymezxcode.networkstateobserver.network.Reachability
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.retryWhen
import kotlinx.coroutines.launch
abstract class BaseActivity : AppCompatActivity() {
override fun onResume() {
super.onResume()
monitorNetworkState()
}
private fun monitorNetworkState() {
lifecycleScope.launch {
val networkObserver = NetworkStateObserver.Builder()
.activity(this@BaseActivity)
.build()
networkObserver.callNetworkConnectionFlow()
.observe()
.collect { status ->
handleNetworkStatus(status)
}
}
}
protected open fun handleNetworkStatus(status: NetworkObserver.Status) {
when (status) {
NetworkObserver.Status.Available -> {
lifecycleScope.launch {
val isConnected = Reachability.hasInternetConnectedFlow(
context = this@BaseActivity,
reachUrl = "https://www.google.com/" //this can be your server url, or any other url
).retryWhen { cause, attempt ->
if (cause is IOException && attempt < 3) {
delay(2000)
true
} else {
false
}
}.buffer().first()
if (isConnected) {
onNetworkRestored()
} else {
onNetworkIssues()
}
}
}
NetworkObserver.Status.Unavailable -> {
showToast("Network is unavailable!")
}
NetworkObserver.Status.Losing -> {
showToast("You are losing your network!")
}
NetworkObserver.Status.Lost -> {
showToast("Network is lost!")
}
}
}
protected open fun onNetworkRestored() {
showToast("Network restored")
}
protected open fun onNetworkIssues() {
showToast("Network is lost or issues with server")
}
protected fun showToast(message: String) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
}
Key Features of BaseActivity:
- monitorNetworkState(): Starts observing network states.
- handleNetworkStatus(): Processes different network statuses (e.g., Available, Unavailable).
- onNetworkRestored() and onNetworkIssues(): Provide hooks to customize behavior in child activities.
Step 3: Implement Child Activities
Here’s how a specific activity can extend the BaseActivity:
package com.example.app.ui
import com.example.app.base.BaseActivity
class HomeActivity : BaseActivity() {
override fun onNetworkRestored() {
super.onNetworkRestored()
// Custom behavior for network restoration
fetchDataFromServer()
}
override fun onNetworkIssues() {
super.onNetworkIssues()
// Custom behavior for network issues
showRetryDialog()
}
private fun fetchDataFromServer() {
// Fetch data from server
}
private fun showRetryDialog() {
// Show a retry dialog to the user
recreate() //or do whatever you want
}
}
Benefits:
- Code Reuse: Shared logic is encapsulated in BaseActivity.
- Custom Behavior: Each activity can override methods to define its unique behavior.
Tips for Using NetworkStateObserver
- Use Dependency Injection: If you’re using DI frameworks like Hilt or Dagger, inject the NetworkStateObserver to avoid recreating it in every activity e.g check the readme on github for more guide on this tip.
- Handle Long Network Requests: Use flows to manage retries and timeouts for long-running network requests.
- Test Network Scenarios: Simulate different network conditions (e.g., airplane mode, slow networks) to ensure robust handling.
- Optimize with ViewModel: If you’re using ViewModel, consider observing network state at the ViewModel level for better lifecycle management.
- Use Analytics: Log network state changes for analytics and debugging.
Conclusion
Integrating NetworkStateObserver into large projects can simplify network monitoring and improve app stability. By creating a reusable BaseActivity, you can manage connectivity across your app efficiently. Customize behavior in individual activities to meet specific needs, and leverage the tips provided to optimize your implementation.
🎉 Happy coding! 🚀
Now it’s time for me to get back to work. 💻😊
Top comments (0)