Kotlin:停止内联线程
Kotlin: Stop In-Line Thread
我已经创建了一些内联线程,但我现在不确定如何停止它们。我有一个线程打开蓝牙套接字连接,一个关闭,一个读取使用自定义列表视图适配器显示数据的数据。我现在想通过单击按钮停止在屏幕上发布数据。但是,我不确定如何停止这些线程。我是否必须将线程移动到单独的可调用 class 继承自线程基 class 的对象?
connectButton.setOnClickListener {
//new thread needed to connect to device and keep rest of app running
Thread(Runnable { //connect bluetooth thread
//cancel discovery in case it was turned on
btAdapter?.cancelDiscovery()
try {
//connect the socket
socket.connect()
//run thread on UI to update socket states
runOnUiThread(Runnable { conStat(socket) })
//new thread needed to read stream and keep rest of app running
Thread(Runnable{ //read bluetooth thread
//keep reading stream as long as it is open
while(true) {
readBytes = try {
inStream.read(inBuffer)
} catch (e: IOException) {
Log.d("IN_STREAM: ", "input stream disconnected")
break
}
//return stream information to UI thread as a list view
runOnUiThread(Runnable {
data.add(inBuffer.copyOf())
dataList.adapter = dataListAdapter(this,data)
dataList.visibility = View.VISIBLE
})
}
}).start()
} catch (e: IOException) {
Log.i("SOCKET: ", "Failed to connect")
Log.i("UUID: ", uuid.toString())
Log.i("Device: ", pairedDevices.elementAt(position).name)
Log.i("Address: ", pairedDevices.elementAt(position).address)
}
}).start()
}
//cancel button closes the socket connection and returns to main activity
cancelButton.setOnClickListener {
//close socket connection
Thread(Runnable { //close bluetooth thread
try {
socket.close()
} catch (e: IOException) {
Log.i("SOCKET: ", "Could not close socket")
}
//return to main activity
runOnUiThread(Runnable {
conStat(socket)
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
})
}).start()
}
exportButton.setOnClickListener {
//how to stop threads?
}
强制停止线程只是一个坏主意,这就是 Thread.stop
被弃用的原因。
所以你可以使用一个标志,比如
val shouldContinue = AtomicBoolean(true)
在数据读取线程中,将"keep reading stream as long as it is open"下的while (true)
替换为while (shouldContinue.get())
;在取消按钮监听器中添加 shouldContinue.set(false)
.
使用 var shouldContinue = true
而不是 AtomicBoolean
可能有效,但不保证一定有效。因此它可能在某些设备上失败,但在您的设备或 Android 模拟器中不会失败,这将是 "fun" 调试。
使用 AsyncTask
and FutureTask
代替线程可能会更好。甚至是 Kotlin 协同程序,但这可能应该留到将来使用...
我已经创建了一些内联线程,但我现在不确定如何停止它们。我有一个线程打开蓝牙套接字连接,一个关闭,一个读取使用自定义列表视图适配器显示数据的数据。我现在想通过单击按钮停止在屏幕上发布数据。但是,我不确定如何停止这些线程。我是否必须将线程移动到单独的可调用 class 继承自线程基 class 的对象?
connectButton.setOnClickListener {
//new thread needed to connect to device and keep rest of app running
Thread(Runnable { //connect bluetooth thread
//cancel discovery in case it was turned on
btAdapter?.cancelDiscovery()
try {
//connect the socket
socket.connect()
//run thread on UI to update socket states
runOnUiThread(Runnable { conStat(socket) })
//new thread needed to read stream and keep rest of app running
Thread(Runnable{ //read bluetooth thread
//keep reading stream as long as it is open
while(true) {
readBytes = try {
inStream.read(inBuffer)
} catch (e: IOException) {
Log.d("IN_STREAM: ", "input stream disconnected")
break
}
//return stream information to UI thread as a list view
runOnUiThread(Runnable {
data.add(inBuffer.copyOf())
dataList.adapter = dataListAdapter(this,data)
dataList.visibility = View.VISIBLE
})
}
}).start()
} catch (e: IOException) {
Log.i("SOCKET: ", "Failed to connect")
Log.i("UUID: ", uuid.toString())
Log.i("Device: ", pairedDevices.elementAt(position).name)
Log.i("Address: ", pairedDevices.elementAt(position).address)
}
}).start()
}
//cancel button closes the socket connection and returns to main activity
cancelButton.setOnClickListener {
//close socket connection
Thread(Runnable { //close bluetooth thread
try {
socket.close()
} catch (e: IOException) {
Log.i("SOCKET: ", "Could not close socket")
}
//return to main activity
runOnUiThread(Runnable {
conStat(socket)
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
})
}).start()
}
exportButton.setOnClickListener {
//how to stop threads?
}
强制停止线程只是一个坏主意,这就是
Thread.stop
被弃用的原因。所以你可以使用一个标志,比如
val shouldContinue = AtomicBoolean(true)
在数据读取线程中,将"keep reading stream as long as it is open"下的
while (true)
替换为while (shouldContinue.get())
;在取消按钮监听器中添加shouldContinue.set(false)
.使用
var shouldContinue = true
而不是AtomicBoolean
可能有效,但不保证一定有效。因此它可能在某些设备上失败,但在您的设备或 Android 模拟器中不会失败,这将是 "fun" 调试。使用
AsyncTask
andFutureTask
代替线程可能会更好。甚至是 Kotlin 协同程序,但这可能应该留到将来使用...