Warm tip: This article is reproduced from stackoverflow.com, please click
kotlin multithreading inner-classes

How to start a thread that is defined in a private inner class?

发布于 2020-03-27 10:32:18

I found this example of how to read from a Bluetooth socket using a separate read thread on the Android developer website. The read thread is defined in the private inner class "ConnectedThread".

class MyBluetoothService(
        // handler that gets info from Bluetooth service
        private val handler: Handler) {

    private inner class ConnectedThread(private val mmSocket: BluetoothSocket) : Thread() {

        private val mmInStream: InputStream = mmSocket.inputStream
        private val mmOutStream: OutputStream = mmSocket.outputStream
        private val mmBuffer: ByteArray = ByteArray(1024) // mmBuffer store for the stream

        override fun run() {
            var numBytes: Int // bytes returned from read()

            // Keep listening to the InputStream until an exception occurs.
            while (true) {
                // Read from the InputStream.
                numBytes = try {
                    mmInStream.read(mmBuffer)
                } catch (e: IOException) {
                    Log.d(TAG, "Input stream was disconnected", e)
                    break
                }

                // Send the obtained bytes to the UI activity.
                val readMsg = handler.obtainMessage(
                        MESSAGE_READ, numBytes, -1,
                        mmBuffer)
                readMsg.sendToTarget()
            }
        }
 //Other functions like write, cancel that I omitted from this example

}

So I added a function in MyBluetoothService to start the read thread:

 @JvmStatic
fun read(){
val reader = ConnectedThread(myBluetoothSocket)
Reader.start()
}

But this gives an immediate error:

Constructor of inner class ConnectedThread can be called only with receiver of containing class

How should I start the thread from the example code?

Questioner
user1725145
Viewed
157
Francesc 2019-07-04 00:15

Your ConnectedThread is an inner class of MyBluetoothService so it can't be instantiated outside an instance of MyBluetoothService.

Change it like this (remove private inner):

class ConnectedThread(private val mmSocket: BluetoothSocket) : Thread() {

You'll have to get access to the service some other way, or alternatively create a factory method in your service that instantiates the thread and returns that.