Android 处理程序,不在 ui 线程中执行 post()
Android handler, perform post() not in the ui thread
从一开始,我虽然 Handler 的方法 post()
和 postDelayed()
在与 UI 线程不同的线程中执行操作,但我决定在其上创建一个 TCP 套接字,但它不工作。
我正在接收 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();
}
}
};
}
Handler#post()
在 Looper
线程上发布消息和可运行程序。 Handler
的默认构造函数会将自己绑定到创建它的 Looper 线程。如果它不在 Looper 线程上,那么它会抛出异常。因此,要在工作线程上使用 Handler,您必须首先创建一个线程并使用 Looper 循环它。然后将给定的 Looper
传递给 Handler
的构造函数。
幸运的是,已经有一个实用程序 class 可以为您完成大部分工作。它被称为HandlerThread。只需创建一个 HandlerThread
,并在需要线程的 Looper 时调用 getLooper
。
EDIT: 默认的Handler构造函数不选择主线程。如果它已经是 Looper 线程,它会选择当前线程。
从一开始,我虽然 Handler 的方法 post()
和 postDelayed()
在与 UI 线程不同的线程中执行操作,但我决定在其上创建一个 TCP 套接字,但它不工作。
我正在接收 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();
}
}
};
}
Handler#post()
在 Looper
线程上发布消息和可运行程序。 Handler
的默认构造函数会将自己绑定到创建它的 Looper 线程。如果它不在 Looper 线程上,那么它会抛出异常。因此,要在工作线程上使用 Handler,您必须首先创建一个线程并使用 Looper 循环它。然后将给定的 Looper
传递给 Handler
的构造函数。
幸运的是,已经有一个实用程序 class 可以为您完成大部分工作。它被称为HandlerThread。只需创建一个 HandlerThread
,并在需要线程的 Looper 时调用 getLooper
。
EDIT: 默认的Handler构造函数不选择主线程。如果它已经是 Looper 线程,它会选择当前线程。