簡體   English   中英

Android Studio Kotlin:嘗試從 inputStream(藍牙)讀取時應用程序凍結

[英]Android Studio Kotlin : App freezes when trying to read from inputStream (Bluetooth)

所以我對 Android Studio 和 Kotlin 完全陌生。 我一直在關注視頻以及從 developer.android.com 查看藍牙概述。 我真的迷失在嘗試從 inputBuffer 連續讀取數據的過程中,並且不知道從哪里開始。 我能夠通過藍牙成功發送數據,但是每當我嘗試連續偵聽數據時,應用程序就會凍結。 任何人都可以幫助詳細說明或幫助逐步完成執行此操作的過程嗎?

package com.example.airboard

import android.app.ProgressDialog
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothSocket
import android.content.Context
import android.os.AsyncTask
import android.os.Bundle
import android.os.Handler
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.control_layout.*
import org.jetbrains.anko.toast
import java.io.IOException
import java.util.*

class ControlActivity: AppCompatActivity() {
    companion object {
        var m_myUUID: UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")
        var m_bluetoothSocket: BluetoothSocket? = null
        lateinit var m_progress: ProgressDialog
        lateinit var m_bluetoothAdapater: BluetoothAdapter
        var m_isConnected: Boolean = false
        lateinit var  m_address: String
        private val mmBuffer: ByteArray = ByteArray(1024)
        private const val TAG = "MY_APP_DEBUG_TAG"
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.control_layout)
        m_address = intent.getStringExtra(SettingsActivity.EXTRA_ADDRESS)!!
        ConnectToDevice(this).execute()

        control_led_on.setOnClickListener { sendCommand("1") }
        control_led_off.setOnClickListener { sendCommand("2") }
        control_led_disconnect.setOnClickListener { disconnect() }
        listen.setOnClickListener { listen() }
    }
    private fun listen() {
        var numBytes: Int // bytes returned from read()

        // Keep listening to the InputStream until an exception occurs.
        //while (true) {
            // Read from the InputStream.
            numBytes = try {
                m_bluetoothSocket!!.inputStream.read(mmBuffer)
            } catch (e: IOException) {
                Log.d(TAG, "Input stream was disconnected", e)
                //break
            }
            toast(numBytes)
            // Send the obtained bytes to the UI activity.

       // }
    }
   private fun sendCommand(input: String){
        if (m_bluetoothSocket != null){
            try {
                m_bluetoothSocket!!.outputStream.write(input.toByteArray())
                Log.i("data", "sending..")
            } catch (e: IOException) {
                e.printStackTrace()
                Log.i("data", "couldn't send")
                }
                return

            }

    }
    private fun disconnect(){
        if (m_bluetoothSocket != null){
            try {
                m_bluetoothSocket!!.close()
                m_bluetoothSocket = null
                m_isConnected = false
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
        finish()
    }

    private class ConnectToDevice(c: Context) : AsyncTask<Void, Void, String>(){
        private var connectSuccess: Boolean = true
        private val context: Context

        init {
            this.context = c
        }
        override fun onPreExecute() {
            super.onPreExecute()
            m_progress = ProgressDialog.show(context, "Connecting...", "please wait")
        }
        override fun doInBackground(vararg p0: Void?) : String? {
            try {
                if (m_bluetoothSocket == null || !m_isConnected){
                    m_bluetoothAdapater = BluetoothAdapter.getDefaultAdapter()
                    val device: BluetoothDevice = m_bluetoothAdapater.getRemoteDevice(m_address)
                    m_bluetoothSocket = device.createInsecureRfcommSocketToServiceRecord(m_myUUID)
                    BluetoothAdapter.getDefaultAdapter().cancelDiscovery()
                    m_bluetoothSocket!!.connect()

                }
            } catch (e: IOException){
                connectSuccess = false
                e.printStackTrace()
            }
            return null
        }
        override fun onPostExecute(result: String?) {
            super.onPostExecute(result)
            if(!connectSuccess){
                Log.i("data", "couldn't connect")
            } else {
                m_isConnected = true
                Log.i("data", "connected")
            }
            m_progress.dismiss()


        }

    }
}

挖掘其他一些問題,也許 ASyncTask 不是這樣做的好選擇?

Android 默認在 UI 線程中運行代碼。 所以你不能在主線程中使用 while(true) 否則 UI 會凍結。 相反,在單獨的線程中執行此任務。 您可以擴展Thread類並檢查該類的 run() 方法中的傳入消息。 查看文檔以獲取更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM