Я столкнулся с довольно неприятной проблемой, пытаясь запрограммировать фрагмент кода, отвечающий за обнаружение устройств Bluetooth.
Согласно Android Studio, этот фрагмент кода верен:
fun discoverDevices(): Observable<BluetoothDevice> {
val discovered: HashSet<BluetoothDevice> = HashSet()
return bluetoothUtil.startDiscovery()
.flatMapObservable { discoveryStarted ->
if (discoveryStarted) {
RxBroadcastReceiver.create(appContext, IntentFilter().apply {
addAction(BluetoothDevice.ACTION_FOUND)
addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)
})
} else {
Observable.error(Throwable("Discovery couldn't be started"))
}
}
.takeUntil { intent ->
intent.action == BluetoothAdapter.ACTION_DISCOVERY_FINISHED
}
.map { intent ->
var bluetoothDevice: BluetoothDevice? = null
if (intent.action == BluetoothDevice.ACTION_FOUND) {
bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
}
if (bluetoothDevice != null && !discovered.contains(bluetoothDevice))
bluetoothDevice
else
null
}
}
Функция объявляет, что она возвращает Observable<BluetoothDevice>, хотя ясно, что функция карты вернет BluetoothDevice?. Кроме того, я пытаюсь заставить его фильтровать нулевые значения, добавляя
.filter {
it != null
}
до конца цепочки условие it != null выделяется как «всегда истинно», а возвращаемое значение внезапно становится Observable<BluetoothDevice?>. Это безумно расстраивает, и я не могу найти решения этой странной проблемы.
Это ошибка Android Studio или я что-то делаю не так?
Которые все еще находятся на экспериментальной стадии, поэтому мне не разрешено использовать их в производственном коде в моей компании.
У них есть «экспериментальное» прозвище, но у них также есть 100% приверженность JetBrains поддержке экспериментального API даже после выпуска. JetBrains также отмечает, что они полностью готовы к производству, за исключением того, что они по-прежнему оставляют за собой право изменять API в окончательной версии.
Этому есть очень простое объяснение: значения null поддерживаются нет в RxJava2.
Использование null приведет к выбросу NullPointerException во время выполнения, как объясняется здесь: Что изменилось в версии 2.0.
В вашем конкретном случае IDE выделяет выражение как «всегда истинное», потому что операторы RxJava2 не поддерживают типы, допускающие значение NULL, поэтому оно никогда не будет генерировать его.
Что ж, это было очевидно, не так ли. Большое спасибо!
Извините за то, что не предоставил прямого ответа, но такая беспорядочная логика, распространенная на несколько функций высшего порядка, стала бы сверхчистым и очевидным циклом, если бы вы использовали Kotlin Coroutines.