首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Kotlin: runOnUiThread未解决的引用

Kotlin: runOnUiThread未解决的引用
EN

Stack Overflow用户
提问于 2019-08-02 16:45:22
回答 4查看 8.7K关注 0票数 6

我试图使用Activity.runOnUiThread(Runnable),但是Android似乎认为这个功能不存在。我已经确定"android.app.Activity“是导入的。

我试图使用线程连接到蓝牙设备并读取数据。我列出了配对设备,并单击其中一个配对设备将我带到第二个屏幕上,在那里我可以连接/断开从所选设备上的套接字。连接和断开正在工作。

我现在正试图从readThread内部类将数据流发送回UI线程,但我无法让runOnUiThread工作。无论我做什么,runOnUiThread都不被认可。

代码语言:javascript
运行
复制
package com.example.idxdatalogger

import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothSocket
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.Log
import android.view.View
import android.app.Activity
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_second.*
import java.io.IOException
import java.io.InputStream
import java.util.*



class SecondActivity : AppCompatActivity() {
    var btAdapter: BluetoothAdapter? = null

    var data = arrayListOf<String>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)

        btAdapter = BluetoothAdapter.getDefaultAdapter()

        val position = (intent.getStringExtra("position"))!!.toInt()
        val uuid = UUID.fromString(intent.getStringExtra("UUID"))

        //textView.text = position.toString()
        //textView2.text = uuid.toString()

        val pairedDevices: Set<BluetoothDevice> = btAdapter!!.bondedDevices

        btDeviceLabel.text = pairedDevices.elementAt(position).name.toString()

        var inStream = connectStream(uuid, position, pairedDevices.elementAt(position), btAdapter)

        conStat(inStream)

        connectButton.setOnClickListener {
            inStream.start()
            conStat(inStream)
        }

        cancelButton.setOnClickListener {
            inStream.cancel()
            conStat(inStream)
            inStream = connectStream(uuid, position, pairedDevices.elementAt(position), btAdapter)
        }

    }

    /*
    change text and button visiblity for connect/disconnect buttons
     */
    fun conStat(inStream: connectStream) {
        if (inStream.socket!!.isConnected) {
            socketStatus.text = getString(R.string.connectionOpened)
            connectButton.visibility = View.INVISIBLE
            cancelButton.visibility = View.VISIBLE
        } else {
            socketStatus.text = getString(R.string.connectionClosed)
            connectButton.visibility = View.VISIBLE
            cancelButton.visibility = View.INVISIBLE
        }

    }

    class connectStream(
        private val uuid: UUID,
        private val position: Int,
        private val device: BluetoothDevice,
        private val adapter: BluetoothAdapter?
    ) : Thread() {
        val socket: BluetoothSocket? = device.createRfcommSocketToServiceRecord(uuid)

        override fun run() {

            adapter?.cancelDiscovery()

            try {
                socket?.connect()

                manageConnection().readThread(socket!!).start()
            } catch (e: IOException) {
                Log.i("SOCKET: ", "Failed to connect")
                Log.i("UUID: ", uuid.toString())
                Log.i("Device: ", device.name)
                Log.i("Address: ", device.address)
            }
        }

        fun cancel() {
            try {
                socket?.close()
            } catch (e: IOException) {
                Log.i("SOCKET: ", "Could not close socket")
            }
        }

    }

    class manageConnection() {
        private val MESSAGE_READ: Int = 0
        inner class readThread(socket: BluetoothSocket) : Thread() {
            private val inStream: InputStream = socket.inputStream
            private val inBuffer: ByteArray = ByteArray(1024)

            override fun run() {
                var readBytes: Int

                while (true) {
                    readBytes = try { inStream.read(inBuffer)
                    } catch (e: IOException) {
                        Log.d("IN_STREAM: ", "Input stream disconnected")
                        break
                    }
                    SecondActivity.runOnUiThread(Runnable {

                    })
                }
            }
        }
    }
}

编辑:

重写我的程序以使用线程(Runnable{}),而不是为每个线程拥有单独的类实例。runOnUiThread现在正在无问题地工作。我已经在下面发布了我的更新代码,但这还没有完全发挥作用。现在,我们可以认为这个问题已经解决了。

代码语言:javascript
运行
复制
package com.example.idxdatalogger

import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothSocket
import android.util.Log
import android.view.View
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.os.*
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_second.*
import java.io.IOException
import java.io.InputStream
import java.util.*

/*

 */
class SecondActivity : AppCompatActivity() {
    var btAdapter: BluetoothAdapter? = null
    var data = arrayListOf<String>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)

        btAdapter = BluetoothAdapter.getDefaultAdapter()

        val position = (intent.getStringExtra("position"))!!.toInt()
        val uuid = UUID.fromString(intent.getStringExtra("UUID"))

        val pairedDevices: Set<BluetoothDevice> = btAdapter!!.bondedDevices
        val device = pairedDevices.elementAt(position)

        btDeviceLabel.text = pairedDevices.elementAt(position).name.toString()

        val socket: BluetoothSocket? = device.createRfcommSocketToServiceRecord(uuid)

        //var inStream = connectStream(uuid, position, pairedDevices.elementAt(position), btAdapter)
        conStat(socket!!)


        val inStream: InputStream = socket.inputStream
        val inBuffer: ByteArray = ByteArray(1024)

        var readBytes : Int

        connectButton.setOnClickListener {
            //connect to device
            Thread(Runnable {
                kotlin.run {
                    btAdapter?.cancelDiscovery()
                    try {
                        socket.connect()
                        runOnUiThread(Runnable { conStat(socket) })
                        //read stream
                        Thread(Runnable{
                            while(true) {
                                readBytes = try {
                                    inStream.read(inBuffer)
                                } catch (e: IOException) {
                                    Log.d("IN_STREAM: ", "input stream disconnected")
                                    break
                                }
                                //return stream information to UI thread
                                runOnUiThread(Runnable {
                                    data.add(inBuffer.toString())
                                    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()

        }

        cancelButton.setOnClickListener {
            //close socket connection
            Thread(Runnable {
                try {
                    socket.close()
                } catch (e: IOException) {
                    Log.i("SOCKET: ", "Could not close socket")
                }
                runOnUiThread(Runnable {
                    conStat(socket)
                    val intent = Intent(this, MainActivity::class.java)
                    startActivity(intent)
                })
            }).start()
        }
    }

    /*
    change text and button visiblity for connect/disconnect buttons
     */
    fun conStat(socket : BluetoothSocket) {
        if (socket.isConnected) {
            socketStatus.text = getString(R.string.connectionOpened)
            connectButton.visibility = View.INVISIBLE
            cancelButton.visibility = View.VISIBLE
        } else {
            socketStatus.text = getString(R.string.connectionClosed)
            connectButton.visibility = View.VISIBLE
            cancelButton.visibility = View.INVISIBLE
        }
    }
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-08-02 16:54:50

必须将inner添加到manageConnection类中,然后只需使用runOnUiThread {}

票数 -1
EN

Stack Overflow用户

发布于 2019-08-02 16:59:30

SecondActivity.runOnUiThread(...)是不正确的,因为您在类上调用方法,而runOnUiThread()方法不是静态的。您需要在Activity类的实例上调用此方法,而不是在类本身上调用。

票数 7
EN

Stack Overflow用户

发布于 2019-08-02 18:39:19

请在这里查看runOnUiThread签名:

代码语言:javascript
运行
复制
    /**
 * Runs the specified action on the UI thread. If the current thread is the UI
 * thread, then the action is executed immediately. If the current thread is
 * not the UI thread, the action is posted to the event queue of the UI thread.
 *
 * @param action the action to run on the UI thread
 */
public final void runOnUiThread(Runnable action) {
    if (Thread.currentThread() != mUiThread) {
        mHandler.post(action);
    } else {
        action.run();
    }
}

很明显,它不是静态方法,因此不能将此方法作为静态方法调用如下:

代码语言:javascript
运行
复制
SomeActivity.runOnUiThread {}

解决方法可以是将SecondActivity作为一个实例传递,然后轻松地对活动实例执行您想做的任何事情。

代码语言:javascript
运行
复制
class myClass(val activity : Activity){

    fun someMethod(){
         activity.runOnUithread{}
        }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57330607

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档