线程运行时Android按钮onClick事件失效问题求助
问题分析与解决
你遇到的核心问题是主线程被无限循环阻塞了,导致UI完全无法响应(包括updateButton的点击事件)。
看一下你的run()方法:你用new Handler().post(new Runnable()把包含无限while(true)循环的逻辑放到了主线程执行。Android的主线程负责所有UI操作和事件响应,一旦被这种无限耗时操作占用,整个界面就会卡死,按钮点击、界面更新这些自然都没法正常工作了。
解决方案:把耗时操作放到子线程,主线程只处理UI/通信
正确的做法是把socket读取这种耗时逻辑放到独立的子线程里,主线程只负责接收子线程的消息并更新UI。下面是修正后的代码示例:
1. 修正线程执行逻辑
把你的run()方法改成这样,让socket读取在子线程跑:
public void startWeightReading() { // 换个更清晰的方法名 new Thread(new Runnable() { @Override public void run() { int counter = 0; // 加个中断标志,方便后续停止线程 while (!Thread.currentThread().isInterrupted()) { counter++; try { String output = ""; if (mmInStream != null) { int bytesRead = mmInStream.read(buffer); // 注意接收read的返回值,避免空读 if (bytesRead > 0) { for (int i = 0; i < bytesRead; i++) { char c = (char) buffer[i]; if (c >= ' ' && c < 'z') { output += c; } } } if (counter % 10 == 0) { System.out.println(counter); // 用LocalBroadcast发送数据到主线程,和原来逻辑一致 Intent intent = new Intent("com.curie.WEIGHT_RECEIVED"); intent.putExtra("Output", output); LocalBroadcastManager.getInstance(InputActivity.getContext()) .sendBroadcastSync(intent); } } // 加个短延时,避免过度占用CPU Thread.sleep(100); } catch (IOException e) { e.printStackTrace(); break; // 连接断开,退出循环 } catch (InterruptedException e) { // 线程被中断,退出循环 Thread.currentThread().interrupt(); break; } } } }).start(); }
2. 修改按钮点击事件调用
在readWeight的点击事件里调用这个修正后的方法:
readWeight.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { inputWindow.setText("helloooooooo worldddddd"); System.out.println("********** PRINTING **********"); // 启动子线程读取数据 connector.startWeightReading(); // readWeight.setVisibility(View.INVISIBLE); } });
3. 额外注意事项
- 线程中断:在Activity销毁时,记得中断这个子线程,避免内存泄漏。比如在
onDestroy()里:@Override protected void onDestroy() { super.onDestroy(); // 如果你的connector持有线程引用,可以调用interrupt() // connector.weightReadingThread.interrupt(); } - 避免空字符串拼接:每次读取socket数据时,先判断实际读取的字节数,不要直接遍历整个buffer,避免把空字节拼进去。
- CPU占用优化:在循环里加个短延时(比如
Thread.sleep(100)),避免子线程一直占用CPU资源。
这样修改后,主线程不会被阻塞,updateButton的点击事件就能正常响应了,同时socket读取也能在后台正常运行~
内容的提问来源于stack exchange,提问作者Collin Urie
相关产品推荐
相关产品推荐

