java - 如何将所有网络操作放在单线程中?

标签 java android multithreading

我正在使用网络,因此我必须使用新线程。这些是我在 SmackClass 中的方法:

public void login(String username,String password) throws XMPPException, SmackException, IOException {
        ConnectionConfiguration configuration=new ConnectionConfiguration("", 5222,"localhost");
        configuration.setSecurityMode(SecurityMode.disabled);
        connection=new XMPPTCPConnection(configuration);
        connection.connect();
        connection.login(username,password);
        chatManager = ChatManager.getInstanceFor(connection);
        chatManager.addChatListener(new ChatManagerListener() {
            public void chatCreated(final Chat chat, final boolean createdLocally) {
                chat.addMessageListener(messageListener);
            }
        });
    }

    public void sendMessage(String to,String message) throws NotConnectedException, XMPPException {
         Chat chat=chatManager.createChat(to,messageListener);
         chat.sendMessage(message);
    }

我正在像这样调用上面的方法(在主类中):

final SmackClass smack=new SmackClass();
        Thread thread=new Thread() {

            @Override
            public void run() {
                try {
                    smack.login("android","test");
                } catch (XMPPException | SmackException | IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        };
        thread.start();
        try {
            smack.sendMessage("pidgin@localhost", "test");
        } catch (NotConnectedException | XMPPException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

我的应用程序为 smack.sendMessage 行提供 nullPointerException ,因为我在 login 方法中设置 chatManager 变量,并且此方法在另一个线程中运行。我知道如果我将 smack.sendMessage 行放入该线程内部,它将起作用。但我不想这样做。因为我将在另一个主类中使用 sendMessage 方法方法。我该如何解决这个问题?我想我需要在单线程(不是 ui 线程)中执行所有网络操作,但是如何执行?

最佳答案

最简单的方法是实现队列。 NetworkThread 总是查看队列是否有任何需要处理的内容。聊天 UI 线程可以将命令放入队列中。

public class NetworkThread implements Runnable {

Queue<Command> queue;

public NetworkThread(Queue<Command> queue) throws IOException {
    this.queue = queue;

}

public void run() {

        while (true) {
            Command command = queue.poll()
            if(command != null){
               command.execute();
            }
        }
}

}

Command 是一个接口(interface),您可以定义它来实现每个网络操作。

interface Command{

   public void execute();

}

class LoginCommand implements Command{

   public void execute(){
       //Do login operation 
   }

}

现在 UI 线程可以将命令对象插入队列,网络线程将负责执行它。您可能还需要实现反向消息返回机制。

关于java - 如何将所有网络操作放在单线程中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27663034/

相关文章:

java - 在 Java 中求样条函数的导数

android - 改造如何在url中使用冒号?

c# - SynchronizationContext 和 InvokeRequired

java - Android 从数组中随机动态改变背景

java - 如何将输入流文件分配给json?

java - OpenCV 使用四点裁剪图像

ios - XCode 断点应该只挂起当前线程

全局配置设置的C#线程安全

java - 我应该为 Java 中的双文字使用多少位有效数字?

java - 无法在 Gson 自定义解串器中初始化 Android.Util.Pair