Android事物:在Raspberry PI 3上通过USB UART接收数据时出现NullPointerException

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android事物:在Raspberry PI 3上通过USB UART接收数据时出现NullPointerException相关的知识,希望对你有一定的参考价值。

在我的代码中,我在UartDeviceCallBack上注册了UartDevice,当我的外围设备通过串口发送数据时,我的应用程序崩溃,出现以下错误:

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 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)

以上是关于Android事物:在Raspberry PI 3上通过USB UART接收数据时出现NullPointerException的主要内容,如果未能解决你的问题,请参考以下文章

在Android和Raspberry Pi 3 Linux之间建立Wifi-Direct连接

在 Android 和 Raspberry Pi 3 Linux 之间建立 Wifi-Direct 连接

Android Things 3 无法从 Raspberry PI 3 上的 rxtx 读取

无法通过 BLE 将 Android 应用程序连接到 Raspberry Pi 3

Android Things:在 Raspberry PI 3 上通过 USB UART 接收数据时出现 NullPointerException

将Raspberry PI 3与Android Things连接到Arduino [已关闭]