即使在初始化之后,接口引用也为null,这使得我无法在Internet连接更改时显示snackbar

问题描述 投票:0回答:2

我正在实现BroadcastReceiver以在互联网连接发生变化时显示Snackbar,因此我创建了一个界面并在3个不同的活动中初始化它以在互联网连接发生变化时执行零食栏代码

我的问题是第二个和第三个活动中的接口引用是空的,但在第一个活动中不是奇怪的

我认为问题可能是我使用相同的接口参考所有三个活动(我有点确定这不是问题但我认为发生了一些我不知道的事情)所以我创建了3个不同的引用,每个引用一个,但这仍然没有解决我的问题

BroadcastReceiver代码:

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()
    }

}

第一个活动相关代码:

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)
    }

}

第二活动相关代码:


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)
    }

}

第三活动相关代码:

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)
    }

}

通过一些调试我发现:

当registerSecondActivityReference被调用时,referene不是null,但是在它之后它再次为null并且与thirdActivityReference相同,因为我知道我从未在代码的任何部分再次将它们赋值为null

奇怪的是,这绝不会发生在firstActivityReference上

抱歉任何不一致这是我的第一个问题。

android android-activity kotlin interface broadcastreceiver
2个回答
0
投票

更改此类 - NetworkChangeReceiver:BroadcastReceiver(){to - object NetworkChangeReceiver:BroadcastReceiver(){

并更改此值 - val networkChangeReceiver = NetworkChangeReceiver()to - val networkChangeReceiver = NetworkChangeReceiver

原因:

您正在使用此行val networkChangeReceiver = NetworkChangeReceiver()在每个活动中创建一个新实例

并使用此代码仅注册第一个活动

val intentFilter = IntentFilter()
    intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE")
    registerReceiver(networkChangeReceiver,intentFilter)

解决方案:使用对象键盘制作广播接收器单例。


0
投票

这是因为每次注册活动时都会创建NetworkChangeReceiver的新引用,并且您注册到连接意图的唯一接收者是第一个。

© www.soinside.com 2019 - 2024. All rights reserved.