Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/197.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我是否正确使用此处理程序和执行器(Android)?_Java_Android - Fatal编程技术网

Java 我是否正确使用此处理程序和执行器(Android)?

Java 我是否正确使用此处理程序和执行器(Android)?,java,android,Java,Android,我有一个执行器,它运行一个while-true循环,用数据ping服务器。现在我需要用这些数据更新UI,所以我使用了一个处理程序 在我的主要活动中,我有: private void createGeneralHandler() { generalHandler = new Handler(Looper.getMainLooper()){ @Override public void handleMessage(Message msg){

我有一个执行器,它运行一个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
只是一个单独文件中的可运行文件,定义如下:

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,我想这是我的主要问题