所以,我在 Android 开发方面还是很新的,而且还在研究 observables。所以我想要实现的是,在蓝牙扫描仪的每次扫描滴答上,scanResult
都会被检查,如果它不在列表中,则观察到的列表 scanned
会得到更新,如果是有效的,并做出一些事情。
我的问题是观察函数只运行一次,然后再也不会运行
2021-03-05 22:18:54.522 32057-32057/? D/devices: Got something []
2021-03-05 22:18:54.522 32057-32057/? D/devices: Start scan
2021-03-05 22:18:55.209 32057-32057/? D/devices: Checking Had128_1_1 in scanned
2021-03-05 22:18:55.212 32057-32057/? D/devices: adding Had128_1_1 in scanned
据我所知,这应该如何工作,他应该在这里_scanned.value?.add(scanResult.device)
更新,观察者应该认识到这一点还是我错了?
id 可能是生命周期所有者的问题吗?
它从 MainActivity 到可组合的 val lifecycleOwner = LocalLifecycleOwner.current
是的,该函数在我的可组合中被调用(正如我所说,如果我按下按钮,我可以在“Got Something []”上看到它第一次运行)
private val _scanned: MutableLiveData<MutableList<BluetoothDevice>> =
MutableLiveData(mutableListOf())
private val scanned: LiveData<MutableList<BluetoothDevice>> get() = _scanned
private val lockScanCallback: ScanCallback = object : ScanCallback() {
override fun onScanResult(callbackType: Int, result: ScanResult?) {
super.onScanResult(callbackType, result)
result?.let { scanResult ->
if (fakeWhitelist.contains(scanResult.device.name)) {
Log.d("devices", "Checking ${scanResult.device.name} in scanned")
val search =
_scanned.value?.find { device -> device.name == scanResult.device.name }
if (search == null) {
Log.d("devices", "adding ${scanResult.device.name} in scanned")
_scanned.value?.add(scanResult.device)
}
}
}
}
}
fun listenForDevices(viewLiveCycleOwner: LifecycleOwner) {
scanned.observe(viewLiveCycleOwner, Observer { deviceList ->
Log.d("devices", "Got something $deviceList")
locationList.value.forEach { locationScaffold ->
val boxNames = locationScaffold.parcelBox.map { it.boxName }
val device = deviceList.last()
Log.d("devices", "$boxNames")
if (!boxNames.contains(device.name)) {
Log.d("devices", "Getting location for ${device.name}")
getLocation(device.name)
}
}
})
startScan()
}
答案 0 :(得分:1)
您的错误在于您从未更改 LiveData
的值。 LiveData
的值可以使用 LiveData.getValue()
检索,并且只能使用 LiveData.setValue()
进行设置,如果您查看一下您的实现,则不会在任何地方使用 set 方法。>
认为改变对象的状态会对它的引用做一些事情,或者以某种方式通知持有它的引用的类,这是一个很常见的误解,但事实并非如此。如果您考虑简化版的 LiveData
,您可以将其分解为具有以下核心功能:
它能够通知观察者的唯一方法是公开一个方法/函数,该方法/函数不仅设置值,而且在必要时通知所有观察者更改。
因此,在您的实现中,您检索了当前值并更改了其状态,但实际上从未为 LiveData
设置新值。
所以代替
liveData.value?.add(newItem)
我们需要做类似的事情
val list = liveData.value
list?.add(newItem)
_mutableLiveData.value = list