【问题标题】:Android asynctask reading from socketAndroid asynctask 从套接字读取
【发布时间】:2012-03-08 08:44:56
【问题描述】:

我在读取/写入正在为其构建应用程序的 tcp 服务器时遇到了一些问题。在最近的一个帖子中,有人建议我改用服务,但这是一个建议使用 asyncTask 的学校项目,所以我不妨去做。

所以我得到的类是我的活动类和异步,活动中没有任何有趣的事情发生,但发送一个正在工作的字符串,所以不能继续使用异步。

    class ServerTask extends AsyncTask<Void, Void, Void>{

        public static String ip = "10.0.2.2";
        public static int port = 2002;
        Socket socket;
        public DataInputStream dis;
        public DataOutputStream dos;
        public String message;

        @Override
        protected Void doInBackground(Void... params) {

            try {
                socket = new Socket(ip, port);
                dis = new DataInputStream(socket.getInputStream());
                dos = new DataOutputStream(socket.getOutputStream());

            } catch (Exception e) {
                Log.i("AsyncTank", "Cannot create Socket");
            }
            while(socket.isConnected()){
                read();                     
                    }
                }

            }
            return null;
        }

        public void write(String message) {
            try {
                if (socket.isConnected()){
                    dos.writeUTF(message);
                    dos.flush();
                } else {
                    Log.i("AsynkTask", "Socket appears to be closed");
                }
            } catch (Exception e) {
                Log.i("AsynkTask", "Writing failed");
            }
        }

        public String read() {
            try {
                if (socket.isConnected()) {
                    message = dis.readLine();
                } else {
                    Log.i("AsyncTask", "Cannot read");
                }
            } catch (Exception e) {
                Log.i("AsyncTask", "Cannot read from stream");
            }
            return message;
        }
    }

我知道的事情,服务器确实收到了消息,但直到我重新启动服务器才更新,这让我相信我没有推送新行或其他东西,这使得它在关闭后全部显示为一行。然而,这也可能是我不负责的服务器,所以我必须阅读。

但是,读取部分不想工作,我不确定如何调用该方法以使其不断侦听并对服务器 sockt 做出反应?我尝试在 doInBackGround 中返回之前创建一个线程,但随后应用程序开始工作了几秒钟,由于内存不足而强制关闭?我需要一个线程来不断地听吗?

您可能会猜到,这样做的全部意义在于进行聊天,因此 read 方法最终应该更新我的活动类中的 textView。 send 方法正在“工作”,但不是应该的,尽管这可能就像我之前所说的那样,服务器正在做一些时髦的事情。

另一个,是否可以像我一样将读取作为一种方法,或者当服务器发送数据然后调用该方法时是否必须做出反应?

编辑 我现在已经将读取的部分或至少其中的一部分移到 doInBackGround 所以它现在

    dis = new BufferedReader(new InputStreamReader(socket.getInputStream()));

    message = dis.readLine();
    Log.i("AsynkTask", "Read : "+message+" this is doInBackGround!");

这与在服务器中简单地对打印行进行硬编码的更改一起使我在客户端中阅读了该行,所以我猜测它现在工作得非常好。

它看起来怎么样?这段代码完全是废话,应该以其他方式完成吗?得到了我的功能,但可以说学习做得更好:)。

【问题讨论】:

    标签: android sockets android-asynctask


    【解决方案1】:

    您应该在 AsyncTask 的 doInBackground() 方法中同时对 Socket 进行写入和读取,因为两者都需要时间并且可能会阻塞主 (UI) 线程。我不知道你是如何调用上面的 write() 方法的,但你可能还想看看这个question that might be related

    【讨论】:

    • 我在 Main 类中实例化了 ServerTask 类,然后简单地执行 serverTask.write(tbMessage.getText().toString());。想过在异步任务中使用它,但我不知道如何在不进行异步 和编写 params[0] 的情况下调用 write 但这意味着我每次都必须执行 serverTask.execute(要写入的文本)并且每次都建立新的连接?
    • 还有一件事,我在 doInBackGround 中打开流并不会让它在我使用流时写入那里?
    • 您可以将读/写放在 AsyncTasks 中并将流作为参数传递。在上面的代码中,doInBackground() 方法中的代码以及对 read() 的调用在后台执行,因为您是从 doInBackground() 调用它。 write() 似乎至少来自您包含的代码。
    • 是的,我考虑过这一点并试图这样做,但我一生都无法弄清楚当它通过时如何使用流?发送一个字符串很容易,只需创建一个新字符串并将其分配给它 string text = params[0] 但是如何让传递的流使用?
    猜你喜欢
    • 2020-03-22
    • 2013-12-26
    • 1970-01-01
    • 2012-07-24
    • 2011-10-29
    • 1970-01-01
    • 1970-01-01
    • 2012-04-24
    相关资源
    最近更新 更多