首页 > 解决方案 > 仅在方法完成时继续

问题描述

我用 Java 为 Windows 制作了一个服务器和一个客户端,一切正常。我必须做一个 Android 客户端,但我在实现它时遇到了一些困难。首先,我不想使用AsyncTask,因为它已被弃用,所以我在互联网上发现我可以使用带有Runnable接口的Threads。在我的活动中,我有这个代码。

if (!Client.getInstance().isConnected()) {
    Client.getInstance().connect();
}

if (Client.getInstance().isConnected()) {
    // Staff to do if the socket is connected
} else {
    ConnectionUtils.serverUnreachable(this);
}     

我创建了客户端类,它是一个单例。在这段代码中,当它运行connect()代码时,客户端不会等待该方法完成,所以它运行 serverUnreachable 方法(一个 AlertDialog 告诉您与服务器的连接不成功(但服务器告诉我客户端已连接)。

public void connect() {
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                socket = new Socket(ip, port);
                out = new ObjectOutputStream(socket.getOutputStream());
                in = new ObjectInputStream(socket.getInputStream());
                connected = true;
            } catch (IOException e) {
                e.printStackTrace();
                connected = false;
            }
        }
    });
    thread.start();
}

连接发生,但在 if 语句中,程序不会等到Client.getIntsance().connect()方法结束。

标签: javaandroidmultithreadingrunnable

解决方案


当您调用 时thread.start(),您正在启动一个新线程,并执行传递给它的 Runnable,但这并不意味着您之前所在的主(UI)线程在那里等待。

它立即继续执行下一条指令,在您的情况下,该指令正在检查connected标志,这在大多数情况下是“为时过早”,因此在您的其他线程将其设置为真之前它将是假的。

您的案例的解决方案是在您的线程完成运行该代码 。如果您需要在主线程上运行它(以便与视图交互),那么您可以使用Activity.runOnUiThread(...)方法。

这是一个例子:

 public void connect() {
    Thread  thread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                socket = new Socket(ip, port);
                out = new ObjectOutputStream(socket.getOutputStream());
                in = new ObjectInputStream(socket.getInputStream());
                connected = true;
            } catch (IOException e) {
                e.printStackTrace();
                connected = false;
            }
            runAfterConnection();
        }
    });
    thread.start();
}

public void runAfterConnection(){

   runOnUiThread(new Runnable() {
        @Override
        public void run() {
          if(Client.getInstance().isConnected()) {
             // Staff to do if the socket is connected
          } else {
             ConnectionUtils.serverUnreachable(this);
          }
        }
   });
}

推荐阅读