You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Java蓝牙数据接收异常:while(true)导致APP无法运行

问题原因

你把蓝牙数据接收的无限while(true)循环直接写在了onCreate方法中——而onCreate是运行在Android的UI主线程里的。主线程一旦被这个死循环持续占用,就无法处理界面绘制、用户点击等UI相关任务,直接导致APP卡死、停止响应。

另外,代码里还有个细节问题:inputStream.read(b)是阻塞式方法,在没读到数据时会一直等待,这会进一步加剧主线程的阻塞。

解决方案

把蓝牙数据接收逻辑移到子线程中执行,同时子线程不能直接修改UI,必须通过Android提供的UI线程切换机制来更新界面。下面是修改后的完整代码示例:

static final UUID mUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private Button button1;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    button1 = findViewById(R.id.button);
    BluetoothAdapter btadapter = BluetoothAdapter.getDefaultAdapter();

    System.out.println(btadapter.getBondedDevices());
    BluetoothDevice hc06 = btadapter.getRemoteDevice("98:D3:31:B3:15:81");
    System.out.println(hc06.getName());
    BluetoothSocket btSocket = null;
    int counter = 0;
    do {
        try {
            btSocket = hc06.createRfcommSocketToServiceRecord(mUUID);
            System.out.println(btSocket);
            btSocket.connect();
            System.out.println(btSocket.isConnected());
        } catch (IOException e) {
            e.printStackTrace();
        }
        counter++;
    } while (btSocket != null && !btSocket.isConnected() && counter < 3);

    // 启动子线程处理蓝牙数据接收
    if (btSocket != null && btSocket.isConnected()) {
        new Thread(() -> {
            InputStream inputStream = null;
            try {
                inputStream = btSocket.getInputStream();
                inputStream.skip(inputStream.available());
                byte[] b = new byte[6];

                while (!Thread.currentThread().isInterrupted()) { // 用线程中断代替死循环,方便后续停止
                    int readLength = inputStream.read(b); // 记录实际读取的字节数,避免空数据问题
                    if (readLength > 0) {
                        System.out.println(b[0]);
                        // 切换回主线程更新UI
                        runOnUiThread(() -> {
                            if (b[0] == 2) {
                                button1.setBackgroundColor(Color.GREEN);
                            } else {
                                button1.setBackgroundColor(Color.RED);
                            }
                        });
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (inputStream != null) inputStream.close();
                    if (btSocket != null) btSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}
关键修改点
  • 把蓝牙接收逻辑放到独立的Thread中,彻底避免阻塞UI主线程。
  • 用Thread.currentThread().isInterrupted()代替while(true),后续可以通过thread.interrupt()安全停止接收线程。
  • 使用runOnUiThread()方法切换回主线程修改按钮颜色,符合Android的UI线程操作规则。
  • 增加了流和Socket的关闭逻辑,避免资源泄漏。
  • 记录inputStream.read()的返回值,确保读到有效数据再处理,避免无效操作。

内容的提问来源于stack exchange,提问作者CoNe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 15:25:19