【发布时间】:2018-06-27 08:48:58
【问题描述】:
我有一个执行器,它运行一个 while true 循环,它只是用数据 ping 一个服务器。现在我需要用这些数据更新 UI,所以我使用了一个处理程序。
在我的主要活动中,我有:
private void createGeneralHandler() {
generalHandler = new Handler(Looper.getMainLooper()){
@Override
public void handleMessage(Message msg){
switch (msg.what){
case SERVER_RESPONSE:
serverTextView.append("\n"+msg.obj);
break;
default:
super.handleMessage(msg);
}
}
};
}
这会在名为generalHandler 的主活动中创建一个字段。
现在NetworkTask runnable 需要知道这个处理程序才能将消息发送到正确的位置?
所以我的主要活动中有这个:
networkExecutor = Executors.newSingleThreadExecutor();
networkTask = new NetworkTask(serverIPAddress, serverPort);
networkTask.setRequest("I WANT DATA");
networkTask.setHandler(generalHandler); //IS THIS WRONG ???
networkExecutor.execute(networkTask);
networkTask 只是一个单独文件中的 Runnable,定义如下:
public class NetworkTask implements Runnable {
private int port;
private String ipAddress;
private int pollInterval;
private Socket socket = null;
private PrintWriter out = null;
private BufferedReader br = null;
private String request = null;
private String response = null;
private static final int SERVER_RESPONSE = 1;
private Handler handler = null;
public NetworkTask(String ipAddress, int port){
this.port = port;
this.ipAddress = ipAddress;
this.pollInterval = 50;
}
@Override
public void run() {
try {
socket = new Socket(ipAddress, port);
out = new PrintWriter(socket.getOutputStream(), true);
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
try {
while (!Thread.currentThread().isInterrupted()) {
Thread.sleep(pollInterval);
out.println(request);
try {
response = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
if(!response.equals("doNothing")){
Message message = new Message();
message.what = SERVER_RESPONSE;
message.obj = response;
handler.sendMessage(message);
}else if(response.equals("Nothing Connected to Server!")){
Message message = new Message();
message.what = SERVER_RESPONSE;
message.obj = response;
handler.sendMessage(message);
}
}
} catch (InterruptedException threadE) {
try {
br.close();
out.close();
socket.close();
} catch (IOException socketE) {
socketE.printStackTrace();
}
Log.i("NETWORK_TASK_THREAD", "NETWORK TASK closed gracefully!");
}
}
public void setRequest(String request) {
this.request = request;
}
public void setHandler(Handler handler) {
this.handler = handler;
}
}
【问题讨论】:
-
与 Handler 关联的 Looper 用于主线程。这怎么不会导致 NetworkOnMainThreadException?
-
@MichaelKrause 我没有在主线程上进行任何网络操作。我只是得到一个服务器响应并将其显示在 textView 上。我是不是做错了什么?