从 Java 到 Kotlin 的反射和调用方法

问题描述

我正在尝试将以下反射转换为 Kotlin。下面使用反射来调用 RFCOMMs 函数,因此它可以将端口/通道作为输入而不是 UUID。我的所有程序都在 Kotlin 中。有人知道如何在 Kotlin 中编写此代码吗?

int bt_port_to_connect = 5;
BluetoothDevice device = mDevice;
BluetoothSocket deviceSocket = null;
...

// IMPORTANT: we create a reference to the 'createInsecureRfcommSocket' method
// and not(!) to the 'createInsecureRfcommSocketToServiceRecord' (which is what the 
// android SDK documentation publishes

Method m = device.getClass().getMethod("createInsecureRfcommSocket",new Class[] {int.class});

deviceSocket = (BluetoothSocket) m.invoke(device,bt_port_to_connect);

更新推荐:

class BluetoothClient(device: BluetoothDevice): Thread() {
    // https://stackoverflow.com/questions/9703779/connecting-to-a-specific-bluetooth-port-on-a-bluetooth-device-using-android
    // Need to reflection - create RFCOMM socket to a port number instead of UUID
    // Invoke btdevice as 1st parameter and then the port number

    var bt_port_to_connect = 5

    var deviceSocket: BluetoothSocket? = null


    private val socket = device.createInsecureRfcommSocketToServiceRecord(uuid)
    val m = device::class.declaredFunctions.single { it.name == "createInsecureRfcommSocket" }
    
    m.call(device,bt_port_to_connect)


    override fun run() {
        try {
            Log.i("client","Connecting")
            this.socket.connect()

            Log.i("client","Sending")
            val outputStream = this.socket.outputStream
            val inputStream = this.socket.inputStream
            try {
                outputStream.write(message.toByteArray())
                outputStream.flush()
                Log.i("client","Sent")
            } catch(e: Exception) {
                Log.e("client","Cannot send",e)
            } finally {
                outputStream.close()
                inputStream.close()
                this.socket.close()
            }
        }
        catch (e: IOException) {
            println("Socket Failed")
        }

    }
}

解决方法

您真的可以使用完全相同的代码,只需将其转换为 Kotlin:

val m = device::class.java.getMethod("createInsecureRfcommSocket",Int::class.java)
m.invoke(device,bt_port_to_connect)

或者你可以使用 Kotlin 反射:

val m = device::class.declaredFunctions.single { it.name == "createInsecureRfcommSocket" }
m.call(device,bt_port_to_connect)

我不知道是否有更好的方法可以找到具有提供名称的函数。您可以创建一个扩展函数以使其更清晰。如果此函数具有覆盖,您可能还需要检查参数。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...