I'm implementing BroadcastReceiver to show Snackbar when internet connection changes, so i created an interface and initialized it in 3 different activities to execute snackbar code when internet connection changes
My problem is that the interface reference in the 2nd and 3rd activity is null but not null in the 1st activity strangely
i thought the problem might be that i use the same interface reference for all the three activities (I was kind of sure that this isn't the problem but i was thinking that something was going on that i don't know of) so i created 3 different references, one for each activity but this still didn't solve my problem
BroadcastReceiver code:
class NetworkChangeReceiver : BroadcastReceiver() {
private var firstActivityReference: InternetSnackbarInterface? = null
private var secondActivityReference: InternetSnackbarInterface? = null
private var thirdActivityReference: InternetSnackbarInterface? = null
fun registerFirstActivityInterface(snackbarInterface: InternetSnackbarInterface) {
this.firstActivityReference= snackbarInterface
}
fun registerSecondActivityInterface(snackbarInterface: InternetSnackbarInterface) {
this.secondActivityReference= snackbarInterface
}
fun registerThirdActivityInterface(snackbarInterface: InternetSnackbarInterface) {
this.thirdActivityReference= snackbarInterface
}
override fun onReceive(context: Context, intent: Intent?) {
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val activeNetworkInfo = connectivityManager.activeNetworkInfo
val isConnected = activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting
if (isConnected){
firstActivityReference?.hideNoInternetSnackbar()
secondActivityReference?.hideNoInternetSnackbar()
thirdActivityReference?.hideNoInternetSnackbar()
}else{
firstActivityReference?.showNoInternetSnackbar("No internet connection")
secondActivityReference?.showNoInternetSnackbar("No internet connection")
thirdActivityReference?.showNoInternetSnackbar("No internet connection")
}
}
interface InternetSnackbarInterface {
fun showNoInternetSnackbar(message: String)
fun hideNoInternetSnackbar()
}
}
first activity related code:
class FirstActivity: AppCompatActivity(),NetworkChangeReceiver.InternetSnackbarInterface{
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val networkChangeReceiver = NetworkChangeReceiver()
networkChangeReceiver.registerFirstActivityInterface(this)
val intentFilter = IntentFilter()
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE")
registerReceiver(networkChangeReceiver,intentFilter)
}
var internetSnackbar : Snackbar? =null
private fun showSnackbar(message : String,length : Int){
val parentLayout = findViewById<View>(android.R.id.content)
internetSnackbar = Snackbar.make(parentLayout, message, length)
internetSnackbar?.show()
}
override fun hideNoInternetSnackbar() {
internetSnackbar?.dismiss()
}
override fun showNoInternetSnackbar(message: String) {
showSnackbar(message, Snackbar.LENGTH_INDEFINITE)
}
}
second activity related code:
class SecondActivity: AppCompatActivity(),NetworkChangeReceiver.InternetSnackbarInterface{
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val networkChangeReceiver = NetworkChangeReceiver()
networkChangeReceiver.registerSecondActivityInterface(this)
}
var internetSnackbar : Snackbar? =null
private fun showSnackbar(message : String,length : Int){
val parentLayout = findViewById<View>(android.R.id.content)
internetSnackbar = Snackbar.make(parentLayout, message, length)
internetSnackbar?.show()
}
override fun hideNoInternetSnackbar() {
internetSnackbar?.dismiss()
}
override fun showNoInternetSnackbar(message: String) {
showSnackbar(message, Snackbar.LENGTH_INDEFINITE)
}
}
third activity related code:
class ThirdActivity: AppCompatActivity(),NetworkChangeReceiver.InternetSnackbarInterface{
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val networkChangeReceiver = NetworkChangeReceiver()
networkChangeReceiver.registerThirdActivityInterface(this)
}
var internetSnackbar : Snackbar? =null
private fun showSnackbar(message : String,length : Int){
val parentLayout = findViewById<View>(android.R.id.content)
internetSnackbar = Snackbar.make(parentLayout, message, length)
internetSnackbar?.show()
}
override fun hideNoInternetSnackbar() {
internetSnackbar?.dismiss()
}
override fun showNoInternetSnackbar(message: String) {
showSnackbar(message, Snackbar.LENGTH_INDEFINITE)
}
}
with some debugging i found out that:
right when registerSecondActivityReference is called the referene is not null but right after that it's null again and the same with the thirdActivityReference knowing that i never assign them to null again in any part of my code
strangely this never happen to firstActivityReference
and sorry for any inconsistency this is my first question here.
Change this -- class NetworkChangeReceiver : BroadcastReceiver() { to -- object NetworkChangeReceiver : BroadcastReceiver() {
and change this -- val networkChangeReceiver = NetworkChangeReceiver() to -- val networkChangeReceiver = NetworkChangeReceiver
Reason:
You are creating a new instance in each activity with this line val networkChangeReceiver = NetworkChangeReceiver()
and registering only first activity using this code
val intentFilter = IntentFilter()
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE")
registerReceiver(networkChangeReceiver,intentFilter)
Solution: Make broadcast receiver singleton using object keyboard.