从 Android 蓝牙套接字接收的数据仅在套接字终止后绘制在折线图中

Data received from Android Bluetooth socket is getting plotted in the line chart only after socket's termination

我最近开始研究 Android、Kotlin 和 MPAndroidChart。我正在开发一个 Android 应用程序,它从蓝牙服务器接收数据,并且应该使用 MPAndroidChart.

实时绘制获得的数据

这是 Kotlin 代码:

package com.example.flowsensor

import ...

class ConnectionActivity:AppCompatActivity() {

    companion object{
        val TAG = "FlowSensor"
        val APP_NAME = "FlowSensor"
        var myUUID: UUID = UUID.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66")
        var mBluetoothSocket: BluetoothSocket? = null
        lateinit var mProgress: ProgressDialog
        lateinit var mBluetoothAdapter: BluetoothAdapter
        var mIsConnected: Boolean = false
        lateinit var mAddress: String
        lateinit var editText:EditText
        lateinit var mChart:LineChart
        var xVal:Int = 0
        var yVal:Int = 0
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT

        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_connection)

        mChart = findViewById<LineChart>(R.id.line_chart)

       receive_button.setOnClickListener{
            ReceiveData()
        }
    }

    //1 parameters missing
    private fun mAddEntry() {
        Log.d(TAG, "yVal : $yVal")
        var mData = mChart.data

        if(mData != null){
            var mDataSet = mData.getDataSetByIndex(0)

            if(mDataSet == null){
                mDataSet = createDataSet()
                mData.addDataSet(mDataSet)
            }

            var mEntry:Entry = Entry( xVal.toFloat(), yVal.toFloat())
            xVal++

            mData.addEntry(mEntry, 0)

            //Notify chart data has changed
            mChart.notifyDataSetChanged()

            //Limit no of visible entries
           // mChart.setVisibleXRange(1f, 6f)
            mChart.setVisibleXRangeMaximum(6f)

            //Scroll to the last entry
            mChart.moveViewToX(xVal.toFloat())
        }
    }

    //1 parameter missing
    private fun createDataSet(): LineDataSet? {
        var mDataSet = LineDataSet(null, "Data vals")

        //mDataSet.setDrawCubic
        mDataSet.cubicIntensity = 0.2f
        mDataSet.axisDependency = YAxis.AxisDependency.LEFT
        mDataSet.setColor(ColorTemplate.getHoloBlue())
        mDataSet.setCircleColor(ColorTemplate.getHoloBlue())
        mDataSet.lineWidth = 2f
        mDataSet.circleSize = 4f
        mDataSet.fillAlpha = 65
        mDataSet.fillColor = ColorTemplate.getHoloBlue()
        mDataSet.highLightColor = Color.rgb(244, 117, 177)
        mDataSet.valueTextColor = Color.WHITE
        mDataSet.valueTextSize = 10f

        return mDataSet
    }

    private fun ReceiveData() {
        val buffer = ByteArray(1024) // buffer store for the stream
        var bytes: Int // bytes returned from read()
        // Keep listening to the InputStream until an exception occurs
        Log.d(TAG, "Inside ReceiveData()")
        while (true) { // Read from the InputStream
            if(mBluetoothSocket != null)
            {
                try {
                    bytes = mBluetoothSocket!!.inputStream.read(buffer)
                    val incomingMessage = String(buffer, 0, bytes)
                    Log.d(TAG, "InputStream: $incomingMessage")
                    yVal = incomingMessage.toInt()
                    mAddEntry()
                } catch (e: IOException) {
                    Log.e(TAG, "write: Error reading Input Stream. " + e.message)
                    break
                }
            }
        }
    }

}

这里是 logcat log 详细模式下的记录。

应用程序在 Main Activity(此处未附加代码)中启动,查找配对设备然后使用 val intent = Intent(this, ConnectionActivity::class.java) intent.putExtra(EXTRA_ADDRESS, address) startActivity(intent)代码,控制到达连接Activity(上面附上的代码)。

应用程序正在成功从服务器接收数据;通过观察验证logcat。在 ReceiveData() 中,我试图将接收到的数据传递给负责绘制图形的 mAddEntry()。但问题是,只有在我终止套接字后才会绘制数据,因此在附加的 logcat 日志中的第 112 行之后,所有数据都会立即绘制(没有数据丢失)。我想实时绘制数据,这就是我面临的问题。

注意:图表绘制已通过使用 timer.scheduleAtFixedRate 在 ConnectionActivity class 中的 onCreate() 内部实时传递虚拟数据进行了独立验证。这按预期工作。

通过在 receive_button onClickListner 中调用 reciveData(),您正在执行 while 循环,该循环将 运行 直到连接蓝牙套接字并且它 运行 在 MainThread 上运行(UIThread) 并且它将阻塞 UI 线程并且不会让任何其他 ui 更新发生 你应该在后台执行 reciveData() 函数,当你想要绘制数据时在图表中,您应该在 ui 线程中传递数据或在 ui 线程

中调用 mAddEntry() 函数