从一开始我虽然Handler的方法post()
和postDelayed()
在与UI线程不同的线程中做了一些事情,但我决定在其上创建一个TCP Socket,但它&#39 ; s不工作。
我收到了NetworkOnMainThreadException
。
有没有办法在UI线程中执行post()
和postDelayed()
任务?
public class ServerHandler extends Handler {
private Socket serverSocket;
public ServerHandler(){
super(new MyHandlerThread("MyHandlerThread").getLooper());
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
public void connectServer()
{
post(serverConnection);
}
public void writeMessage(String msg){
try {
serverSocket.getOutputStream().write(msg.getBytes());
Log.d("MyLog","Message sent!");
}
catch (IOException io){
Log.d("MyLog","SendMessage error");
}
}
private Runnable serverConnection = new Runnable() {
@Override
public void run() {
try {
serverSocket = new Socket("152.168.21.24", 5001);
Log.d("MyLog","Server connected!");
while(true){
Log.d("MyLog","Listening server");
byte[] buffer = new byte[256];
int bytesReceived = serverSocket.getInputStream().read(buffer);
if(bytesReceived==-1) {
throw new IOException("Server disconnected");
}
else {
String msg = new String(buffer,0,bytesReceived);
Log.d("MyLog","Message received: " + msg);
}
}
}
catch (IOException io){
Log.d("MyLog","Server connection error " + io.getMessage());
connectServer();
}
}
};
}
答案 0 :(得分:5)
Handler#post()
在Looper
个帖子上发布消息和Runnables。 Handler
的默认构造函数将自己绑定到创建它的Looper线程。如果它不在Looper线程上,那么它会抛出异常。因此,要在工作线程上使用Handler,必须首先创建一个线程并使用Looper循环它。然后,您将给定的Looper
传递给Handler
的构造函数。
幸运的是,已经有一个实用工具类可以完成大部分工作。它被称为HandlerThread。只需创建HandlerThread
,并在需要线程的Looper时调用getLooper
。
编辑:默认处理程序构造函数不选择主线程。如果它已经是一个Looper线程,它会选择当前线程。