Android 事情:在 Raspberry PI 3 上通过 USB UART 接收数据时发生 NullPointerException
Android Things: NullPointerException when receiving data over USB UART on Raspberry PI 3
在我的代码中,我在 UartDevice
上注册了一个 UartDeviceCallBack
,当我的外围设备通过串行发送数据时,我的应用程序崩溃并出现以下错误:
E/AndroidRuntime: FATAL EXCEPTION: main Process: co.foodles.posapp, PID: 1655 java.lang.NullPointerException: Attempt to invoke virtual method 'boolean com.google.android.things.pio.UartDeviceCallback.onUartDeviceDataAvailable(com.google.android.things.pio.UartDevice)' on a null object reference
at com.google.android.things.pio.UartDeviceImpl$UartDeviceCallbackDispatch.dispatchInterruptEvent(UartDeviceImpl.java:245)
at com.google.android.things.pio.CallbackDispatch.onFileDescriptorEvents(CallbackDispatch.java:149)
at android.os.MessageQueue.dispatchEvents(MessageQueue.java:284)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:325)
at android.os.Looper.loop(Looper.java:142)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
这是我的 Uart
设备的 class :
class RFideas80581AK0(peripheralManagerService : PeripheralManagerService): Closeable {
companion object {
private val LOG_TAG = RFideas80581AK0::class.java.simpleName
private val UART_DEVICE_NAME = "USB1-1.2:1.0"
private val BAUDRATE = 57600
private val DATA_SIZE = 8
private val PARITY = UartDevice.PARITY_NONE
private val STOP_BIT = 1
}
private var mDevice : UartDevice? = getDevice(peripheralManagerService, UART_DEVICE_NAME,
BAUDRATE, DATA_SIZE, PARITY, STOP_BIT)
private val uartDeviceCallBack = CustomUartCallBack()
var readCallBack : ((String) -> (Unit))? = null
private fun getDevice(peripheralManagerService: PeripheralManagerService, name : String,
baudrate : Int, dataSize : Int, parity : Int, stopBit : Int)
: UartDevice? =
try { peripheralManagerService.openUartDevice(name).also {
it.setBaudrate(baudrate)
it.setDataSize(dataSize)
it.setParity(parity)
it.setStopBits(stopBit)
it.registerUartDeviceCallback(uartDeviceCallBack)
Log.d(LOG_TAG, "configured device ${it.name}")
}
} catch (e : IOException){
Log.e(LOG_TAG, "error while opening UartDevice on address $UART_DEVICE_NAME",e)
null
}
override fun close() {
Log.d(LOG_TAG, "close")
mDevice = mDevice?.let {
try {
it.unregisterUartDeviceCallback(uartDeviceCallBack)
it.close()
} catch (e : IOException){
Log.e(LOG_TAG, "error while closing UartDevice",e)
throw e
}
null
}
}
private fun convertAsciiNumbersToHexString(asciiNumbers : String) : String {
var hexString = BigInteger(asciiNumbers).toString(16)
if (hexString.length %2 == 1) hexString = "0"+hexString
return hexString.windowed(2, 2).reversed().joinToString("").toUpperCase()
}
override fun readUartBuffer(uartDevice: UartDevice) : String {
val maxCount = 128
val buffer = ByteArray(maxCount)
uartDevice.read(buffer, maxCount)
return convertAsciiNumbersToHexString(String(buffer).takeWhile { it.isDigit() })
}
inner class CustomUartCallBack : UartDeviceCallback(){
override fun onUartDeviceDataAvailable(uart: UartDevice): Boolean {
try {
readCallBack?.invoke(readUartBuffer(uart))
} catch (e : IOException){
Log.e(LOG_TAG, "error while reading uart buffer",e)
}
return true
}
override fun onUartDeviceError(uart: UartDevice, error: Int) {
Log.e(LOG_TAG, "error $error in CustomUartCallBack")
}
}
}
有线索吗?
感谢 Onik,这是正确的实现:
class RFideas80581AK0(peripheralManagerService : PeripheralManagerService): Closeable {
companion object {
private val LOG_TAG = RFideas80581AK0::class.java.simpleName
private val UART_DEVICE_NAME = "USB1-1.2:1.0"
private val BAUDRATE = 57600
private val DATA_SIZE = 8
private val PARITY = UartDevice.PARITY_NONE
private val STOP_BIT = 1
}
private val uartDeviceCallBack = CustomUartCallBack()
var readCallBack : ((String) -> (Unit))? = null
private var mDevice : UartDevice? = getDevice(peripheralManagerService, UART_DEVICE_NAME,
BAUDRATE, DATA_SIZE, PARITY, STOP_BIT)
private fun getDevice(peripheralManagerService: PeripheralManagerService, name : String,
baudrate : Int, dataSize : Int, parity : Int, stopBit : Int)
: UartDevice? =
try { peripheralManagerService.openUartDevice(name).also {
it.setBaudrate(baudrate)
it.setDataSize(dataSize)
it.setParity(parity)
it.setStopBits(stopBit)
it.registerUartDeviceCallback(uartDeviceCallBack)
Log.d(LOG_TAG, "configured device ${it.name}")
}
} catch (e : IOException){
Log.e(LOG_TAG, "error while opening UartDevice on address $UART_DEVICE_NAME",e)
null
}
override fun close() {
Log.d(LOG_TAG, "close")
mDevice = mDevice?.let {
try {
it.unregisterUartDeviceCallback(uartDeviceCallBack)
it.close()
} catch (e : IOException){
Log.e(LOG_TAG, "error while closing UartDevice",e)
throw e
}
null
}
}
private fun convertAsciiNumbersToHexString(asciiNumbers : String) : String {
var hexString = BigInteger(asciiNumbers).toString(16)
if (hexString.length %2 == 1) hexString = "0"+hexString
return hexString.windowed(2, 2).reversed().joinToString("").toUpperCase()
}
override fun readUartBuffer(uartDevice: UartDevice) : String {
val maxCount = 128
val buffer = ByteArray(maxCount)
uartDevice.read(buffer, maxCount)
return convertAsciiNumbersToHexString(String(buffer).takeWhile { it.isDigit() })
}
inner class CustomUartCallBack : UartDeviceCallback(){
override fun onUartDeviceDataAvailable(uart: UartDevice): Boolean {
try {
readCallBack?.invoke(readUartBuffer(uart))
} catch (e : IOException){
Log.e(LOG_TAG, "error while reading uart buffer",e)
}
return true
}
override fun onUartDeviceError(uart: UartDevice, error: Int) {
Log.e(LOG_TAG, "error $error in CustomUartCallBack")
}
}
}
当行 private var mDevice : UartDevice? = getDevice(..)
被调用时,uartDeviceCallBack
仍然引用 null
因为它的实例化发生在更远的一行。更改行的顺序:
private val uartDeviceCallBack = CustomUartCallBack()
private var mDevice : UartDevice? = getDevice(peripheralManagerService, UART_DEVICE_NAME,
BAUDRATE, DATA_SIZE, PARITY, STOP_BIT)
在我的代码中,我在 UartDevice
上注册了一个 UartDeviceCallBack
,当我的外围设备通过串行发送数据时,我的应用程序崩溃并出现以下错误:
E/AndroidRuntime: FATAL EXCEPTION: main Process: co.foodles.posapp, PID: 1655 java.lang.NullPointerException: Attempt to invoke virtual method 'boolean com.google.android.things.pio.UartDeviceCallback.onUartDeviceDataAvailable(com.google.android.things.pio.UartDevice)' on a null object reference
at com.google.android.things.pio.UartDeviceImpl$UartDeviceCallbackDispatch.dispatchInterruptEvent(UartDeviceImpl.java:245)
at com.google.android.things.pio.CallbackDispatch.onFileDescriptorEvents(CallbackDispatch.java:149)
at android.os.MessageQueue.dispatchEvents(MessageQueue.java:284)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:325)
at android.os.Looper.loop(Looper.java:142)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
这是我的 Uart
设备的 class :
class RFideas80581AK0(peripheralManagerService : PeripheralManagerService): Closeable {
companion object {
private val LOG_TAG = RFideas80581AK0::class.java.simpleName
private val UART_DEVICE_NAME = "USB1-1.2:1.0"
private val BAUDRATE = 57600
private val DATA_SIZE = 8
private val PARITY = UartDevice.PARITY_NONE
private val STOP_BIT = 1
}
private var mDevice : UartDevice? = getDevice(peripheralManagerService, UART_DEVICE_NAME,
BAUDRATE, DATA_SIZE, PARITY, STOP_BIT)
private val uartDeviceCallBack = CustomUartCallBack()
var readCallBack : ((String) -> (Unit))? = null
private fun getDevice(peripheralManagerService: PeripheralManagerService, name : String,
baudrate : Int, dataSize : Int, parity : Int, stopBit : Int)
: UartDevice? =
try { peripheralManagerService.openUartDevice(name).also {
it.setBaudrate(baudrate)
it.setDataSize(dataSize)
it.setParity(parity)
it.setStopBits(stopBit)
it.registerUartDeviceCallback(uartDeviceCallBack)
Log.d(LOG_TAG, "configured device ${it.name}")
}
} catch (e : IOException){
Log.e(LOG_TAG, "error while opening UartDevice on address $UART_DEVICE_NAME",e)
null
}
override fun close() {
Log.d(LOG_TAG, "close")
mDevice = mDevice?.let {
try {
it.unregisterUartDeviceCallback(uartDeviceCallBack)
it.close()
} catch (e : IOException){
Log.e(LOG_TAG, "error while closing UartDevice",e)
throw e
}
null
}
}
private fun convertAsciiNumbersToHexString(asciiNumbers : String) : String {
var hexString = BigInteger(asciiNumbers).toString(16)
if (hexString.length %2 == 1) hexString = "0"+hexString
return hexString.windowed(2, 2).reversed().joinToString("").toUpperCase()
}
override fun readUartBuffer(uartDevice: UartDevice) : String {
val maxCount = 128
val buffer = ByteArray(maxCount)
uartDevice.read(buffer, maxCount)
return convertAsciiNumbersToHexString(String(buffer).takeWhile { it.isDigit() })
}
inner class CustomUartCallBack : UartDeviceCallback(){
override fun onUartDeviceDataAvailable(uart: UartDevice): Boolean {
try {
readCallBack?.invoke(readUartBuffer(uart))
} catch (e : IOException){
Log.e(LOG_TAG, "error while reading uart buffer",e)
}
return true
}
override fun onUartDeviceError(uart: UartDevice, error: Int) {
Log.e(LOG_TAG, "error $error in CustomUartCallBack")
}
}
}
有线索吗?
感谢 Onik,这是正确的实现:
class RFideas80581AK0(peripheralManagerService : PeripheralManagerService): Closeable {
companion object {
private val LOG_TAG = RFideas80581AK0::class.java.simpleName
private val UART_DEVICE_NAME = "USB1-1.2:1.0"
private val BAUDRATE = 57600
private val DATA_SIZE = 8
private val PARITY = UartDevice.PARITY_NONE
private val STOP_BIT = 1
}
private val uartDeviceCallBack = CustomUartCallBack()
var readCallBack : ((String) -> (Unit))? = null
private var mDevice : UartDevice? = getDevice(peripheralManagerService, UART_DEVICE_NAME,
BAUDRATE, DATA_SIZE, PARITY, STOP_BIT)
private fun getDevice(peripheralManagerService: PeripheralManagerService, name : String,
baudrate : Int, dataSize : Int, parity : Int, stopBit : Int)
: UartDevice? =
try { peripheralManagerService.openUartDevice(name).also {
it.setBaudrate(baudrate)
it.setDataSize(dataSize)
it.setParity(parity)
it.setStopBits(stopBit)
it.registerUartDeviceCallback(uartDeviceCallBack)
Log.d(LOG_TAG, "configured device ${it.name}")
}
} catch (e : IOException){
Log.e(LOG_TAG, "error while opening UartDevice on address $UART_DEVICE_NAME",e)
null
}
override fun close() {
Log.d(LOG_TAG, "close")
mDevice = mDevice?.let {
try {
it.unregisterUartDeviceCallback(uartDeviceCallBack)
it.close()
} catch (e : IOException){
Log.e(LOG_TAG, "error while closing UartDevice",e)
throw e
}
null
}
}
private fun convertAsciiNumbersToHexString(asciiNumbers : String) : String {
var hexString = BigInteger(asciiNumbers).toString(16)
if (hexString.length %2 == 1) hexString = "0"+hexString
return hexString.windowed(2, 2).reversed().joinToString("").toUpperCase()
}
override fun readUartBuffer(uartDevice: UartDevice) : String {
val maxCount = 128
val buffer = ByteArray(maxCount)
uartDevice.read(buffer, maxCount)
return convertAsciiNumbersToHexString(String(buffer).takeWhile { it.isDigit() })
}
inner class CustomUartCallBack : UartDeviceCallback(){
override fun onUartDeviceDataAvailable(uart: UartDevice): Boolean {
try {
readCallBack?.invoke(readUartBuffer(uart))
} catch (e : IOException){
Log.e(LOG_TAG, "error while reading uart buffer",e)
}
return true
}
override fun onUartDeviceError(uart: UartDevice, error: Int) {
Log.e(LOG_TAG, "error $error in CustomUartCallBack")
}
}
}
当行 private var mDevice : UartDevice? = getDevice(..)
被调用时,uartDeviceCallBack
仍然引用 null
因为它的实例化发生在更远的一行。更改行的顺序:
private val uartDeviceCallBack = CustomUartCallBack()
private var mDevice : UartDevice? = getDevice(peripheralManagerService, UART_DEVICE_NAME,
BAUDRATE, DATA_SIZE, PARITY, STOP_BIT)