首页 > 解决方案 > Kotlin:停止内联线程

问题描述

我已经创建了一些内联线程,现在我不确定如何阻止它们。我有一个线程来打开蓝牙套接字连接,一个用于关闭,一个用于读取使用自定义列表视图适配器显示数据的数据。我现在想通过单击按钮停止在屏幕上发布数据。但是,我不确定如何停止这些线程。我是否必须将线程移动到从线程基类继承的可调用类中?

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?
        }

标签: androidmultithreadingkotlinbluetooth

解决方案


  1. 强行停止线程只是一个坏主意,这就是Thread.stop不推荐使用的原因。

  2. 所以你可以使用一个标志,比如

    val shouldContinue = AtomicBoolean(true)
    

    在数据读取线程中,将while (true)“只要打开就保持读取流”下替换为while (shouldContinue.get());在取消按钮监听器中添加shouldContinue.set(false).

    使用var shouldContinue = true代替AtomicBoolean可能有效,但不能保证有效。所以它可能会在某些设备上失败,但不会在你的设备或 Android 模拟器上失败,这将是“有趣”的调试。

  3. AsyncTask使用andFutureTask而不是线程可能会更好。甚至是 Kotlin 协程,但这可能应该留给未来......


推荐阅读