接口引用即使在初始化后仍为空,使我无法在 Internet 连接更改时显示小吃栏
Posted
技术标签:
【中文标题】接口引用即使在初始化后仍为空,使我无法在 Internet 连接更改时显示小吃栏【英文标题】:Interface reference is null even after it got initialized making me unable to show snackbar when internet connection changes 【发布时间】:2019-09-09 10:42:10 【问题描述】:我正在实现 BroadcastReceiver 以在 Internet 连接更改时显示 Snackbar,因此我创建了一个接口并在 3 个不同的活动中对其进行了初始化,以便在 Internet 连接更改时执行 snapbar 代码
我的问题是第二个和第三个活动中的接口引用为空,但奇怪的是在第一个活动中不为空
我认为问题可能是我对所有三个活动都使用了相同的接口引用(我有点确定这不是问题,但我认为发生了一些我不知道的事情) 所以我创建了 3 个不同的引用,每个活动一个,但这仍然没有解决我的问题
广播接收方代码:
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 不为空,但在此之后它再次为空 与第三个ActivityReference 相同 知道我再也不会在我的代码的任何部分将它们分配给 null
奇怪的是,firstActivityReference 从来没有发生过这种情况
对于任何不一致之处,这是我在这里的第一个问题。
【问题讨论】:
【参考方案1】:改变这个 -- 类 NetworkChangeReceiver : BroadcastReceiver() 到 -- 对象 NetworkChangeReceiver : BroadcastReceiver()
和 改变这个 -- val networkChangeReceiver = NetworkChangeReceiver() 到 -- val networkChangeReceiver = NetworkChangeReceiver
原因:
您正在使用此行在每个活动中创建一个新实例 val networkChangeReceiver = NetworkChangeReceiver()
并使用此代码仅注册第一个活动
val intentFilter = IntentFilter()
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE")
registerReceiver(networkChangeReceiver,intentFilter)
解决方案: 使用对象键盘制作广播接收器单例。
【讨论】:
是的!我怎么会错过这个!,onReceive 函数被注册了 BroadcastReceiver 的对象调用,这总是使其他 2 个引用为 null【参考方案2】:这是因为您每次注册活动时都会创建一个NetworkChangeReceiver
的新引用,而您注册到连接意图的唯一接收者是第一个。
【讨论】:
以上是关于接口引用即使在初始化后仍为空,使我无法在 Internet 连接更改时显示小吃栏的主要内容,如果未能解决你的问题,请参考以下文章
Django中的JSONField即使在POST请求后仍保持为空
graphql.js:即使解析器正在为 sequilize 查询返回值,该字段仍为空
安装完NetBeans后程序显示为乱码,已更改过conf文件,打开后仍为乱码
Pentaho 数据集成,插入/更新步骤即使在发现一些错误后仍继续