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

时间:2014-12-26 23:34:46

标签: 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();
        }

我的应用程序正在为nullPointerException行提供smack.sendMessage,因为我在chatManager方法中设置login变量,此方法正在另一个线程中运行。我知道是否放了smack.sendMessage在这个帖子里面就行了。但是我不想这样做。因为我会在另一个主类方法中使用sendMessage方法。如何解决这个问题?我想我需要在单线程(不是ui线程)中进行所有网络操作,但是如何?

1 个答案:

答案 0 :(得分:0)

最简单的方法是实现队列。如果要处理任何内容,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();
            }
        }
}

}

命令是您可以定义的接口,用于实现每个网络操作。

interface Command{

   public void execute();

}

class LoginCommand implements Command{

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

}

现在UI线程可以将一个Command Object推入队列,网络线程将负责执行它。你可能还需要反向实现消息返回机制。