繁体   English   中英

套接字不接收数据。 (Android / Java)

[英]Socket does not receive data. (Android/Java)

我的Android程序的MainActivity产生了另一个活动,称为SecondActivity,该活动又创建了另一个活动,称为TempActivity。

SecondActivity创建一个套接字并建立与服务器的连接。 然后,它将该套接字等同于称为SocketHandler的类的静态套接字对象(以便其他线程可以在该套接字上写入/读取数据)。

启动时,TempActivity应该向服务器发送一条消息(“ get temp”),以提示它开始每隔5秒发送一次温度读数,然后将其显示在Android设备上的文本框中。

我的问题是,当我启动应用程序并启动一次TempActivity时,读数显示良好。 但是当我按回去并再次启动TempActivity时,我不再收到任何读数。 我不知道是什么引起了这个问题。

SecondActivity看起来像这样:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);
    new Thread(new ClientThread()).start();
}
class ClientThread implements Runnable {
    @Override
    public void run() {
        try {
            InetAddress serverAddr = InetAddress.getByName("192.168.0.152");
            sockfd = new Socket(serverAddr, port);
            SocketHandler.setSocket(sockfd);
            out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(sockfd.getOutputStream())),true);
            try {
                input = new BufferedReader(new InputStreamReader(sockfd.getInputStream()));
            }
            catch (IOException e) {
                e.printStackTrace();
            }   
        } 

        catch (UnknownHostException e1) {
            e1.printStackTrace();
        } 
        catch (IOException e1) {
            e1.printStackTrace();
        }
    }
}

我的TempActivity看起来像这样:

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_temp);

    sockfd2 = SocketHandler.getSocket();
    temp = (TextView) findViewById(R.id.tempreading);

    //Output stream
    try{
    out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(sockfd2.getOutputStream())),true);
    out.println("get temp");
    }
    catch (Exception e)
    {
    }

    //InputStream
    try {
        input = new BufferedReader(new InputStreamReader(sockfd2.getInputStream()));
         new Thread(new TempRecv()).start();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
  class TempRecv implements Runnable {
       @Override
       public void run() {  
        while(true)
        {
         try{
           reading=input.readLine();
           runOnUiThread(showmessage);
           }
           catch(IOException e)
           {
           }
        }
       }

    }

   Runnable showmessage = new Runnable() {
        public void run() {
                   temp.setText(reading);
            }
        };

    @Override
    public void onBackPressed()
    {
        out.println("stop temp");
        this.finish();
    }

不要将数据存储在Activity中 如果用户转动屏幕,您的“活动”将从屏幕上删除并重新创建。 (您可以将屏幕锁定在一个方向上,但这不会阻止Android尝试重新创建您的Activity,这只会使重现此行为更加困难)。

MVCModel-View-Controller )的角度来看,Activity是一个Controller ,该View是您使用布局XML所获得的(有时人们定义自定义View类,例如TextViewWithImages ,但在大多数情况下将重用现有的类)。

Model是必须在屏幕转向后生存下来的东西。 我会为此使用单例。

我必须注意,有时(在内存不足的情况下)Android可以终止进程并稍后重新创建它,从而重新设置所有静态变量。 这就是为什么Activity在将来使用包将数据传递给自己的原因。 所有这些听起来都是精神分裂症(实际上,您不能仅将应用程序状态存储在变量中,您必须保存和恢复所有内容,至少在两种格式之间进行转换),但是进程并不经常被终止,因此我将从包含应用程序数据的单例开始。

稍后,您可以添加保存/还原应用程序数据和/或实施服务(听起来好像数据还是在后台下载)。

您不需要Service即可运行后台工作线程,但是需要Model Singleton来使用该线程检索的数据。

您正在使用BufferedWriter,因此将“ get temp”命令写入缓冲区,但是缓冲区永远不会传输,因为只有在缓冲区已满或刷新时才会发生。

因此,简单的解决方案是根据需要进行无缓冲通信而消除BufferedWriter

out = new PrintWriter(new OutputStreamWriter(sockfd2.getOutputStream()),true);

一种替代方法是冲洗out编写器:

out.flush();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM