Android Socket接收树莓派温湿度数据调用TextView.setText报错如何解决?
错误根因
- Android系统规定所有UI控件的更新操作必须在主线程(UI线程)执行,你的
StartThread是自定义子线程,直接在子线程调用temphum.setText()会直接触发CalledFromWrongThreadException崩溃 - 你当前转字符串的方式会残留无效内容:每次创建的64字节
buffer如果没有被数据填满,未填充的字节会被转成乱码/空白字符,导致TextView显示冗余旧内容
修复方案
1. 修正StartThread的循环逻辑,切主线程更新UI+清理无效字符
直接替换你的StartThread类代码即可:
class StartThread extends Thread{ int bytes; // 增加退出标记,避免线程一直运行导致内存泄漏 private boolean isRunning = true; public StartThread(){ } // 点击停止按钮时调用该方法终止接收循环 public void stopReceive() { isRunning = false; } public void run(){ try { Log.d(TAG, "데이터 수신 준비"); // 把流初始化移到循环外,避免重复创建对象 InputStream input = socket.getInputStream(); byte[] buffer = new byte[64]; while (isRunning) { bytes = input.read(buffer); if(bytes <= 0) break; // 连接断开/读取结束直接退出循环 // 只转换实际读取到的字节长度,trim去掉首尾空白/换行符,避免残留无效内容 String sensor = new String(buffer, 0, bytes).trim(); Log.d(TAG, "data = " + sensor); // 切换到主线程更新UI runOnUiThread(new Runnable() { @Override public void run() { // setText会直接覆盖旧内容,无需额外清理 temphum.setText("data = " + sensor); } }); } }catch(IOException e){ e.printStackTrace(); Log.e(TAG,"수신 에러"); } } }
2. 修正按钮逻辑,增加线程控制
先把StartThread声明为全局变量,方便停止时调用:
// 加到成员变量声明区域 private StartThread sthread;
修改StartButton和StopButton的点击逻辑:
StartButton.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View view) { sthread = new StartThread(); StartButton.setEnabled(false); StopButton.setEnabled(true); sthread.start(); } }); StopButton.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View view) { // 先终止接收线程 if(sthread != null) { sthread.stopReceive(); } StopThread spthread = new StopThread(); StartButton.setEnabled(true); StopButton.setEnabled(false); spthread.start(); } });
补充说明
setText()方法本身会直接覆盖TextView的原有内容,只要传入的sensor字符串清理掉了冗余无效字符,就会自动展示最新的传感器数据,不需要额外做刷新/删除旧数据操作。
内容的提问来源于stack exchange,提问作者user17135507
相关产品推荐
相关产品推荐

