如何解决使用 DrawerLayout 时,viewLifecycleOwner 获取空值
我的片段中有以下功能 -
private fun getOffenderInfo(device: BleDevice) {
val offenderInfoRequest = OffenderInfoBody(activity?.sharedPreferences?.deviceId,activity?.sharedPreferences?.token,listOf(TagItem(device.tagID)))
offenderViewModel.getOffenderInfo(offenderInfoRequest).observe(viewLifecycleOwner,{ offenders ->
when (offenders) {
is Resource.Loading -> {
}
is Resource.Success -> {
updateUI(offenders.data,device)
}
is Resource.Exception -> {
}
}
})
}
这是由我找到 BLE 设备触发的 -
private fun initViews() {
//.....Other not relevant code
bleManager = BLEManager { bleDevice ->
handleDeviceFound(bleDevice)
}
}
// Handle BLE device found
private fun handleDeviceFound(device: BleDevice) {
// check if bleDevice with this TAG_ID already exist in bleDevices
bleDevices.find { it.tagID == device.tagID } ?: return addDevice(device)
if (device.bleOffender == null || device.bleOffender?.status == -1)
return getOffenderInfo(device)
val offenderDeviceData = tagDecryption.parseTagData(device,tagDecryption.decryptOffenderDetails(device))
handleDeviceData(offenderDeviceData)
}
// adding new device to bleDevices & update adapter
private fun addDevice(device: BleDevice) {
bleDevices.add(device)
tagsAdapter.addDevice(device)
binding.fragmentScannerClearButton.isEnabled = bleDevices.isNotEmpty()
return getOffenderInfo(device)
}
并且正在调用我的 ViewModel 中的一个方法来访问本地和远程数据 -
fun getOffenderInfo(offenderInfoBody: OffenderInfoBody) = liveData(Dispatchers.IO) {
emit(Resource.Loading<Nothing>())
emit(offenderRepository.getOffenderInfo(offenderInfoBody))
}
问题是,当我在 BLE 扫描期间在 DrawerLayout 中的 Fragment 之间切换并且 livedata 观察者开始观察时,应用程序崩溃并出现以下错误
java.lang.IllegalStateException: Can't access the Fragment View's LifecycleOwner when getView() is null i.e.,before onCreateView() or after onDestroyView()
Fragment 是可通过 DrawerLayout 访问的 3 个片段之一。
如果我不在扫描期间,我可以毫无问题地切换。
据我所知,livedata 功能不应该导致这个问题,只是停止观察者,虽然它不会。
我错过了什么?
编辑 -
我的 BLEManager 类 -
class BLEManager(private val onBleScanResult: (device: BleDevice) -> Unit) : BluetoothAdapter.LeScanCallback {
override fun onLeScan(device: BluetoothDevice?,rssi: Int,scanRecord: ByteArray?) {
if (scanRecord == null || device == null) return
// siteCode validation indicates that tag is SuperCom tag
val siteCode = scanRecord[5].toInt() and 0xFF
val tagID: Int = (scanRecord[6].toInt() and 0xFF) + (scanRecord[7].toInt() and 0xFF) * 256 + (scanRecord[8].toInt() and 0xFF) * 65536
// validate TagId isn't equals to 0
// if (tagID != 0 && (tagID == 2467 || tagID == 3004)) { }// remove *&& (tagID == 2467 || tagID == 3004)* in production (used only for testing)
if (tagID == 0) return
val bleDevice = BleDevice(device = device,tagID = tagID.toString(),rssi = rssi,scanRecord = scanRecord)
onBleScanResult(bleDevice)
}
}
解决方法
修复它的最简单方法是在片段被破坏时停止扫描
override fun onDestroyView() {
super.onDestroyView()
bleScanner.stopScan(bleManager)
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。