安卓 | Kotlin:应用程序从 InputStream 读取到缓冲区问题

Posted

技术标签:

【中文标题】安卓 | Kotlin:应用程序从 InputStream 读取到缓冲区问题【英文标题】:Android | Kotlin : App Reading from InputStream to Buffer Problems 【发布时间】:2021-02-17 23:33:02 【问题描述】:

我开始在接收数据和应用播放声音之间遇到一些延迟问题。以前我只使用 SoundPool 加载了 5 个声音并且延迟接近 0,但现在在创建额外的 42 个变量以加载不同的声音以及增加我的输入缓冲区之后,我遇到了这些延迟问题。我不确定这是因为评估缓冲区元素需要多长时间,还是因为我包含了所有额外的变量来存储 SoundPool 声音。有什么方法可以让我的代码在使用所有这些变量方面更有效率?

编辑(2/17/21):发现虽然将缓冲区元素输出到 logcat,但有时接收到的数据有时会被一个元素关闭,有时不会。我从输入缓冲区读取信息的方式一定有问题,但我一生都无法弄清楚

编辑(2/19/21):似乎只有在数组 > 大小 6 时才会出现问题 还发现当输入流接收到一个输入时,它会额外读取 2-4 次,而且都具有不同的值

这是我的代码 sn-p 功能发生的地方:

private class ConnectedThread(private val mmSocket: BluetoothSocket?, c: Context) : Thread() 
        private val mmBuffer: ByteArray = ByteArray(12) // mmBuffer store for the stream
        private var a1 = 0
        private var b1 = 0
        private var c1 = 0
        private var d1 = 0
        private var e1 = 0
        private var f1 = 0
        private var g1 = 0

        private var a2 = 0
        private var b2 = 0
        private var c2 = 0
        private var d2 = 0
        private var e2 = 0
        private var f2 = 0
        private var g2 = 0

        private var a3 = 0
        private var b3 = 0
        private var c3 = 0
        private var d3 = 0
        private var e3 = 0
        private var f3 = 0
        private var g3 = 0

        private var a4 = 0
        private var b4 = 0
        private var c4 = 0
        private var d4 = 0
        private var e4 = 0
        private var f4 = 0
        private var g4 = 0

        private var a5 = 0
        private var b5 = 0
        private var c5 = 0
        private var d5 = 0
        private var e5 = 0
        private var f5 = 0
        private var g5 = 0

        private var a6 = 0
        private var b6 = 0
        private var c6 = 0
        private var d6 = 0
        private var e6 = 0
        private var f6 = 0
        private var g6 = 0

        private var soundPool: SoundPool? = null
        private var soundStream1: Int? = 0
        private var soundStream2: Int? = 0
        private var soundStream3: Int? = 0
        private var soundStream4: Int? = 0
        private var soundStream5: Int? = 0
        private var temp: ByteArray = ByteArray(12)
        var read: Int = 0
        var context: Context

        init 
            this.context = c
        

        override fun run() 
            var numBytes: Int = 0// bytes returned from read()
            soundPool = SoundPool(10, AudioManager.STREAM_MUSIC, 0)
            a1 = soundPool!!.load(context, R.raw.c4, 1)
            b1 = soundPool!!.load(context, R.raw.d4, 1)
            c1 = soundPool!!.load(context, R.raw.e4, 1)
            d1 = soundPool!!.load(context, R.raw.f4, 1)
            e1 = soundPool!!.load(context, R.raw.g4, 1)
            f1 = soundPool!!.load(context, R.raw.c4, 1)
            g1 = soundPool!!.load(context, R.raw.d4, 1)

            a2 = soundPool!!.load(context, R.raw.c4, 1)
            b2 = soundPool!!.load(context, R.raw.d4, 1)
            c2 = soundPool!!.load(context, R.raw.e4, 1)
            d2 = soundPool!!.load(context, R.raw.f4, 1)
            e2 = soundPool!!.load(context, R.raw.g4, 1)
            f2 = soundPool!!.load(context, R.raw.c4, 1)
            g2 = soundPool!!.load(context, R.raw.d4, 1)

            a3 = soundPool!!.load(context, R.raw.a3, 1)
            b3 = soundPool!!.load(context, R.raw.b3, 1)
            c3 = soundPool!!.load(context, R.raw.c3, 1)
            d3 = soundPool!!.load(context, R.raw.d3, 1)
            e3 = soundPool!!.load(context, R.raw.e3, 1)
            f3 = soundPool!!.load(context, R.raw.f3, 1)
            g3 = soundPool!!.load(context, R.raw.g3, 1)

            a4 = soundPool!!.load(context, R.raw.a4, 1)
            b4 = soundPool!!.load(context, R.raw.b4, 1)
            c4 = soundPool!!.load(context, R.raw.c4, 1)
            d4 = soundPool!!.load(context, R.raw.d4, 1)
            e4 = soundPool!!.load(context, R.raw.e4, 1)
            f4 = soundPool!!.load(context, R.raw.f4, 1)
            g4 = soundPool!!.load(context, R.raw.g4, 1)

            a5 = soundPool!!.load(context, R.raw.a5, 1)
           b5 = soundPool!!.load(context, R.raw.b4, 1)
            c5 = soundPool!!.load(context, R.raw.c5, 1)
            d5 = soundPool!!.load(context, R.raw.d5, 1)
            e5 = soundPool!!.load(context, R.raw.e5, 1)
            f5 = soundPool!!.load(context, R.raw.f5, 1)
            g5 = soundPool!!.load(context, R.raw.g5, 1)

            a6 = soundPool!!.load(context, R.raw.c4, 1)
            b6 = soundPool!!.load(context, R.raw.d4, 1)
            c6 = soundPool!!.load(context, R.raw.c6, 1)
            d6 = soundPool!!.load(context, R.raw.f4, 1)
            e6 = soundPool!!.load(context, R.raw.g4, 1)
            f6 = soundPool!!.load(context, R.raw.c4, 1)
            g6 = soundPool!!.load(context, R.raw.d4, 1)


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

                playNote(mmBuffer)


            
        

        fun playNote(buf: ByteArray) 
            var count: Int = 0

            if (read == 0) 
                read++
             else 
                for (i in buf) 
                    Log.i("data", count.toString() + " " + i.toString())
                    if (i != '0'.toByte()) 
                        when (count) 
                            2 -> 
                                if(buf[count] != temp[count] && buf[count+1] != temp[count+1])
                                    soundPool?.stop(soundStream1!!)
                                
                                soundStream1 = noteCheck(buf[count], buf[count + 1])
                            
                            4 -> 
                                if(buf[count] != temp[count] && buf[count+1] != temp[count+1])
                                    soundPool?.stop(soundStream2!!)
                                
                                soundStream2 = noteCheck(buf[count],buf[count+1])
                            
                            6 -> 
                                if(buf[count] != temp[count] && buf[count+1] != temp[count+1])
                                    soundPool?.stop(soundStream3!!)
                                
                                soundStream3 = noteCheck(buf[count],buf[count+1])
                            
                            8 -> 
                                if(buf[count] != temp[count] && buf[count+1] != temp[count+1])
                                    soundPool?.stop(soundStream4!!)
                                
                                soundStream4 = noteCheck(buf[count],buf[count+1])
                            
                            10 -> 
                                if(buf[count] != temp[count] && buf[count+1] != temp[count+1])
                                    soundPool?.stop(soundStream5!!)
                                
                                soundStream5 = noteCheck(buf[count],buf[count+1])
                            
                        
                        temp[count] = i
                     else if (i == '0'.toByte()) 

                        temp[count] = i
                    
                    count++
                
                read = 0

            


        
        fun noteCheck(check1 : Byte, check2 : Byte): Int? 
            var sndStream: Int? = 0
            if (check1 == 'a'.toByte()) 

                when (check2) 
                    '1'.toByte() -> sndStream= soundPool?.play(a1, 1F, 1F, 0, 0, 1F)
                    '2'.toByte() -> sndStream= soundPool?.play(a2, 1F, 1F, 0, 0, 1F)
                    '3'.toByte() -> sndStream= soundPool?.play(a3, 1F, 1F, 0, 0, 1F)
                    '4'.toByte() -> sndStream= soundPool?.play(a4, 1F, 1F, 0, 0, 1F)
                    '5'.toByte() -> sndStream= soundPool?.play(a5, 1F, 1F, 0, 0, 1F)
                    '6'.toByte() -> sndStream= soundPool?.play(a6, 1F, 1F, 0, 0, 1F)
                
             else if (check1 == 'b'.toByte()) 

                when (check2) 
                    '1'.toByte() -> sndStream= soundPool?.play(b1, 1F, 1F, 0, 0, 1F)
                    '2'.toByte() -> sndStream= soundPool?.play(b2, 1F, 1F, 0, 0, 1F)
                    '3'.toByte() -> sndStream= soundPool?.play(b3, 1F, 1F, 0, 0, 1F)
                    '4'.toByte() -> sndStream= soundPool?.play(b4, 1F, 1F, 0, 0, 1F)
                    '5'.toByte() -> sndStream= soundPool?.play(b5, 1F, 1F, 0, 0, 1F)
                    '6'.toByte() -> sndStream= soundPool?.play(b6, 1F, 1F, 0, 0, 1F)
                
             else if (check1 == 'c'.toByte()) 

                when (check2) 
                    '1'.toByte() -> sndStream= soundPool?.play(c1, 1F, 1F, 0, 0, 1F)
                    '2'.toByte() -> sndStream= soundPool?.play(c2, 1F, 1F, 0, 0, 1F)
                    '3'.toByte() -> sndStream= soundPool?.play(c3, 1F, 1F, 0, 0, 1F)
                    '4'.toByte() -> sndStream= soundPool?.play(c4, 1F, 1F, 0, 0, 1F)
                    '5'.toByte() -> sndStream= soundPool?.play(c5, 1F, 1F, 0, 0, 1F)
                    '6'.toByte() -> sndStream= soundPool?.play(c6, 1F, 1F, 0, 0, 1F)
                
             else if (check1 == 'd'.toByte()) 

                when (check2) 
                    '1'.toByte() -> sndStream= soundPool?.play(d1, 1F, 1F, 0, 0, 1F)
                    '2'.toByte() -> sndStream= soundPool?.play(d2, 1F, 1F, 0, 0, 1F)
                    '3'.toByte() -> sndStream= soundPool?.play(d3, 1F, 1F, 0, 0, 1F)
                    '4'.toByte() -> sndStream= soundPool?.play(d4, 1F, 1F, 0, 0, 1F)
                    '5'.toByte() -> sndStream= soundPool?.play(d5, 1F, 1F, 0, 0, 1F)
                    '6'.toByte() -> sndStream= soundPool?.play(d6, 1F, 1F, 0, 0, 1F)
                
             else if (check1 == 'e'.toByte()) 

                when (check2) 
                    '1'.toByte() -> sndStream= soundPool?.play(e1, 1F, 1F, 0, 0, 1F)
                    '2'.toByte() -> sndStream= soundPool?.play(e2, 1F, 1F, 0, 0, 1F)
                    '3'.toByte() -> sndStream= soundPool?.play(e3, 1F, 1F, 0, 0, 1F)
                    '4'.toByte() -> sndStream= soundPool?.play(e4, 1F, 1F, 0, 0, 1F)
                    '5'.toByte() -> sndStream= soundPool?.play(e5, 1F, 1F, 0, 0, 1F)
                    '6'.toByte() -> sndStream= soundPool?.play(e6, 1F, 1F, 0, 0, 1F)
                
             else if (check1 == 'f'.toByte()) 

                when (check2) 
                    '1'.toByte() -> sndStream= soundPool?.play(f1, 1F, 1F, 0, 0, 1F)
                    '2'.toByte() -> sndStream= soundPool?.play(f2, 1F, 1F, 0, 0, 1F)
                    '3'.toByte() -> sndStream= soundPool?.play(f3, 1F, 1F, 0, 0, 1F)
                    '4'.toByte() -> sndStream= soundPool?.play(f4, 1F, 1F, 0, 0, 1F)
                    '5'.toByte() -> sndStream= soundPool?.play(f5, 1F, 1F, 0, 0, 1F)
                    '6'.toByte() -> sndStream= soundPool?.play(f6, 1F, 1F, 0, 0, 1F)
                
             else if (check1 == 'g'.toByte()) 

                when (check2) 
                    '1'.toByte() -> sndStream=
                        soundPool?.play(g1, 1F, 1F, 0, 0, 1F)
                    '2'.toByte() -> sndStream=
                        soundPool?.play(g2, 1F, 1F, 0, 0, 1F)
                    '3'.toByte() -> sndStream=
                        soundPool?.play(g3, 1F, 1F, 0, 0, 1F)
                    '4'.toByte() -> sndStream=
                        soundPool?.play(g4, 1F, 1F, 0, 0, 1F)
                    '5'.toByte() -> sndStream=
                        soundPool?.play(g5, 1F, 1F, 0, 0, 1F)
                    '6'.toByte() -> sndStream=
                        soundPool?.play(g6, 1F, 1F, 0, 0, 1F)
                
            

        return sndStream
        


    

Logcat 输出:我每次都发送完全相同的数据,但有时会有所不同

2021-02-19 04:08:24.408 16533-21821/com.example.airboard I/data: ---------------------------------------------
2021-02-19 04:08:24.408 16533-21821/com.example.airboard I/data: 0 48
2021-02-19 04:08:24.408 16533-21821/com.example.airboard I/data: 1 97
2021-02-19 04:08:24.408 16533-21821/com.example.airboard I/data: 2 51
2021-02-19 04:08:24.408 16533-21821/com.example.airboard I/data: 3 98
2021-02-19 04:08:24.408 16533-21821/com.example.airboard I/data: 4 51
2021-02-19 04:08:24.408 16533-21821/com.example.airboard I/data: 5 48
2021-02-19 04:08:24.408 16533-21821/com.example.airboard I/data: 6 48
2021-02-19 04:08:24.408 16533-21821/com.example.airboard I/data: 7 100
2021-02-19 04:08:24.408 16533-21821/com.example.airboard I/data: 8 51
2021-02-19 04:08:24.408 16533-21821/com.example.airboard I/data: 9 101
2021-02-19 04:08:24.408 16533-21821/com.example.airboard I/data: 10 51
2021-02-19 04:08:24.408 16533-21821/com.example.airboard I/data: 11 48
2021-02-19 04:08:24.594 16533-21821/com.example.airboard I/data: ---------------------------------------------
2021-02-19 04:08:24.594 16533-21821/com.example.airboard I/data: 0 48
2021-02-19 04:08:24.594 16533-21821/com.example.airboard I/data: 1 48
2021-02-19 04:08:24.594 16533-21821/com.example.airboard I/data: 2 51
2021-02-19 04:08:24.595 16533-21821/com.example.airboard I/data: 3 98
2021-02-19 04:08:24.595 16533-21821/com.example.airboard I/data: 4 51
2021-02-19 04:08:24.595 16533-21821/com.example.airboard I/data: 5 48
2021-02-19 04:08:24.595 16533-21821/com.example.airboard I/data: 6 48
2021-02-19 04:08:24.595 16533-21821/com.example.airboard I/data: 7 100
2021-02-19 04:08:24.595 16533-21821/com.example.airboard I/data: 8 51
2021-02-19 04:08:24.595 16533-21821/com.example.airboard I/data: 9 101
2021-02-19 04:08:24.595 16533-21821/com.example.airboard I/data: 10 48
2021-02-19 04:08:24.595 16533-21821/com.example.airboard I/data: 11 48
2021-02-19 04:08:24.627 16533-21821/com.example.airboard I/data: ---------------------------------------------
2021-02-19 04:08:24.627 16533-21821/com.example.airboard I/data: 0 48
2021-02-19 04:08:24.627 16533-21821/com.example.airboard I/data: 1 97
2021-02-19 04:08:24.627 16533-21821/com.example.airboard I/data: 2 51
2021-02-19 04:08:24.627 16533-21821/com.example.airboard I/data: 3 98
2021-02-19 04:08:24.627 16533-21821/com.example.airboard I/data: 4 51
2021-02-19 04:08:24.627 16533-21821/com.example.airboard I/data: 5 48
2021-02-19 04:08:24.627 16533-21821/com.example.airboard I/data: 6 48
2021-02-19 04:08:24.627 16533-21821/com.example.airboard I/data: 7 100
2021-02-19 04:08:24.627 16533-21821/com.example.airboard I/data: 8 51
2021-02-19 04:08:24.627 16533-21821/com.example.airboard I/data: 9 51
2021-02-19 04:08:24.627 16533-21821/com.example.airboard I/data: 10 48
2021-02-19 04:08:24.627 16533-21821/com.example.airboard I/data: 11 48
2021-02-19 04:08:24.814 16533-21821/com.example.airboard I/data: ---------------------------------------------
2021-02-19 04:08:24.814 16533-21821/com.example.airboard I/data: 0 48
2021-02-19 04:08:24.814 16533-21821/com.example.airboard I/data: 1 97
2021-02-19 04:08:24.814 16533-21821/com.example.airboard I/data: 2 51
2021-02-19 04:08:24.814 16533-21821/com.example.airboard I/data: 3 98
2021-02-19 04:08:24.814 16533-21821/com.example.airboard I/data: 4 51
2021-02-19 04:08:24.814 16533-21821/com.example.airboard I/data: 5 48
2021-02-19 04:08:24.814 16533-21821/com.example.airboard I/data: 6 48
2021-02-19 04:08:24.814 16533-21821/com.example.airboard I/data: 7 100
2021-02-19 04:08:24.814 16533-21821/com.example.airboard I/data: 8 51
2021-02-19 04:08:24.815 16533-21821/com.example.airboard I/data: 9 101
2021-02-19 04:08:24.815 16533-21821/com.example.airboard I/data: 10 51
2021-02-19 04:08:24.815 16533-21821/com.example.airboard I/data: 11 48

【问题讨论】:

【参考方案1】:

显然,我的解决方案是弄清楚将数据读入 ByteArray,然后评估它是否无法正常工作。将我的阅读行更改为:

                           val ch =  mmSocket!!.inputStream.read().toChar()
                            mmBuffer[c23] = ch
                            c23++

并将我的缓冲区从 ByteArray 更改为 CharArray 并获得了更好的结果。

【讨论】:

以上是关于安卓 | Kotlin:应用程序从 InputStream 读取到缓冲区问题的主要内容,如果未能解决你的问题,请参考以下文章

为什么我们建议尝试一下新颖简洁的现代语言Kotlin?

沪江技术沙龙 -- Kotlin 我们一路走来

一款纯 Kotlin 编写的开源安卓应用

Java与Kotlin, 哪个是开发安卓应用的首选语言?

Java被抛弃?大量安卓程序员涌向Kotlin!

安卓app开发 一般用啥语言