[英]Why the UI thread is getting blocked?
在下面的代码中,我试图在单击按钮时运行一个线程。 在按钮监听器中,我创建一个新线程并运行它...但是在运行时,按下按钮时,按钮本身会冻结,应用程序不响应,我收到ANR
对话框。 而且,当插座连接成功时甚至连TexView
mtvStatus.setText("RFC-SOCKET CONNECTED");
没有显示。
请让我知道为什么会这样。
按钮监听器 :
this.mbtnConnect.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
BluetoothSocket rfcSocket = mSPPCtrl.rfcConnect();
if (rfcSocket.isConnected()) {
mtvStatus.setText("RFC-SOCKET CONNECTED");
Thread rx = new Thread(new RxRun(rfcSocket));
rx.run();
} else {
mtvStatus.setText("RFC-SOCKET NOT CONNECTED");
}
}
});
可运行的类
private class RxRun implements Runnable {
private BluetoothSocket mRFCSocket = null;
private OutputStream mRFCOS = null;
private InputStream mRFCIS = null;
public RxRun(BluetoothSocket rfcSocket) {
this.mRFCSocket = rfcSocket;
try {
this.mRFCOS = rfcSocket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
try {
this.mRFCIS = rfcSocket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
this.mRFCOS.write(DIRON.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
while (this.mRFCSocket.isConnected()) {
try {
int readBytes = this.mRFCIS.read(new byte[5120]);
Log.d(TAG, CSubTag.bullet("RxRun", "readBytes:" + readBytes));
//mtvRx.setText(""+readBytes);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
...当按下按钮时,按钮本身冻结,应用程序没有响应,我收到
ANR
对话框。 而且,当插座连接成功时,即使TexView
显示任何内容。
这是预期的,因为你还没有真正启动rx
线程。 这是正在发生的事情:
mSPPCtrl
连接, mtvStatus
的文本设置为"RFC-SOCKET CONNECTED"
,但您无法直观地看到它,因为 RxRun
实例的run()
方法,其中循环while (this.mRFCSocket.isConnected())
可以在套接字连接时持续。 所有上述内容都是在UI
-thread上调用的,这就是ANR
的原因。
你不应该手动调用run()
。 用。启动rx
线程
rx.start();
另外,我强烈建议将所有rfcSocket
逻辑移到线程内部,并在连接成功/失败时通知UI
-thread。
这是我的评论中提到的一个选项。
单击按钮启动rx
线程
this.mbtnConnect.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new RxRun(rfcSocket)).start();
}
});
在run()
方法中移动逻辑:
public void run() {
BluetoothSocket rfcSocket = mSPPCtrl.rfcConnect();
if (rfcSocket.isConnected()) {
mtvStatus.post(new Runnable() {
@Override
public void run() {
mtvStatus.setText("RFC-SOCKET CONNECTED");
}
});
} else {
mtvStatus.post(new Runnable() {
@Override
public void run() {
mtvStatus.setText("RFC-SOCKET NOT CONNECTED");
}
});
return;
}
// the rest of your logic
}
一些可能有用的链接:
这里的错误非常简单 - 不要在Thread实例上使用run()
,因为这实际上会在当前Thread上运行它的Runnable ! 使用start()
,它会正常工作:-)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.