使用 DrawerLayout 时 viewLifecycleOwner 获取空值
viewLifecycleOwner gets null value when working with DrawerLayout
我的 Fragment 中有以下功能 -
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 之间切换时,实时数据观察器开始转向,应用程序崩溃并出现以下错误
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 个 fragment 之一。
如果我不在扫描期间,我可以毫无问题地切换。
据我所知,livedata 功能不应该导致这个问题,只是停止观察者,尽管它不会。
我错过了什么?
编辑-
我的 BLEManager class -
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)
}
我的 Fragment 中有以下功能 -
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 之间切换时,实时数据观察器开始转向,应用程序崩溃并出现以下错误
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 个 fragment 之一。
如果我不在扫描期间,我可以毫无问题地切换。
据我所知,livedata 功能不应该导致这个问题,只是停止观察者,尽管它不会。
我错过了什么?
编辑-
我的 BLEManager class -
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)
}