接口引用即使在初始化后也为空,这使我无法在互联网连接发生变化时显示小吃店

Interface reference is null even after it got initialized making me unable to show snackbar when internet connection changes

我正在实施 BroadcastReceiver 以在 Internet 连接发生变化时显示 Snackbar,因此我创建了一个界面并在 3 个不同的活动中对其进行了初始化,以便在 Internet 连接发生变化时执行 snackbar 代码

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

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

广播接收者代码:

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

}

第一个activity相关代码:

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

}

秒activity相关代码:


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

}

第三activity相关代码:

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

对于任何不一致之处,这是我的第一个问题。

这是因为您在每次注册 activity 时都创建了一个新的 NetworkChangeReceiver 引用,并且您注册到 Connectivity Intent 的唯一接收者是第一个。

改变这个 -- class NetworkChangeReceiver : BroadcastReceiver() { 到 -- 对象 NetworkChangeReceiver : BroadcastReceiver() {

和 改变这个 -- val networkChangeReceiver = NetworkChangeReceiver() 到 -- val networkChangeReceiver = NetworkChangeReceiver

原因:

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

并且仅首先 activity 使用此代码

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

解决方法: 使用对象键盘使广播接收器成为单例。