关于java:Android处理程序,不在ui线程中执行post()

Android handler, perform post() not in the ui thread

从一开始,我虽然Handler的方法post()postDelayed()在与UI线程不同的线程中执行操作,所以我决定在该线程上创建一个TCP套接字,但是它不起作用。

我正在接收NetworkOnMainThreadException被抛出。

有没有办法在UI线程中执行post()postDelayed()任务?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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线程上,则会抛出异常。 因此,要在辅助线程上使用处理程序,必须首先创建一个线程并使用Looper对其进行循环。 然后,将给定的Looper传递给Handler的构造函数。

幸运的是,已经有一个实用程序类可以为您完成大部分工作。 它称为HandlerThread。 只需创建一个HandlerThread,并在需要该线程的Looper时调用getLooper

编辑:默认处理程序构造函数不选择主线程。 如果已经是Looper线程,它将选择当前线程。