Java 我是否正确使用此处理程序和执行器(Android)?
我有一个执行器,它运行一个while-true循环,用数据ping服务器。现在我需要用这些数据更新UI,所以我使用了一个处理程序 在我的主要活动中,我有:Java 我是否正确使用此处理程序和执行器(Android)?,java,android,Java,Android,我有一个执行器,它运行一个while-true循环,用数据ping服务器。现在我需要用这些数据更新UI,所以我使用了一个处理程序 在我的主要活动中,我有: private void createGeneralHandler() { generalHandler = new Handler(Looper.getMainLooper()){ @Override public void handleMessage(Message msg){
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
只是一个单独文件中的可运行文件,定义如下:
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;
}
}
对你的问题的回答会有点武断。因为实现只是一个设计选择,所以不会有对错,但会有好的或不好的 以下是我想强调的几点:
- 如果您只是关心
networkTask.setHandler(generalHandler)代码>然后,只要不调用任何网络调用或主线程上的繁重处理,就可以了
- 您还需要确保在应用程序
或onStop()
中适当中断您的运行,以避免潜在的内存泄漏onDestroy()
- 您不断尝试ping服务器,这不是一个好主意,因为它会消耗资源并耗尽电池。您可以定期执行这些任务,也可以使用FCM推送
- 要关闭InputStreams或OutputStreams,最好在
块中进行清理,以确保在执行过程中发生其他异常时进行清理finally{..}
一种替代方法是实现
ViewModel
和MutableLiveData
并执行该操作。这不会因为不必要的处理而使您的活动膨胀。与处理程序关联的活套用于主线程。这怎么不会导致NetworkOnMainThreadException?@MichaelKrause我没有在主线程上执行任何网络操作。我只是得到一个服务器响应,并将其显示在textView上。我做错什么了吗?好的,谢谢你的反馈。服务器一直在发送数据,所以我必须不断ping它。你可以看到我有一根线;定期做。您有什么建议?@TrtTrt ping的持续时间太小。我会建议使用JobScheduler/Workmanager,但它的最短持续时间是15分钟。增加ping是否有帮助?我不确定应该采用什么方法。@TrtTrt如果没有必要如此频繁地ping,那么与WorkManager安排一次定期工作,频率为15分钟。这也将保证即使应用程序未运行,也能执行工作。你可以在这里查看我的答案。我有必要尽可能频繁地ping,我想这是我的主要问题