套接字不接收数据。 (机器人/爪哇)

时间:2015-05-06 12:33:02

标签: java android sockets networking

我的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();
    }

2 个答案:

答案 0 :(得分:0)

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

MVC 模型 - 视图 - 控制器)的角度来看,Activity是 Controller View 是您使用布局XML获得的(有时人们定义自定义的 View 类,如TextViewWithImages,但在大多数情况下,现有的类被重用)。

模型是屏幕转向必须存活的东西。我会用一个单身人士。

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

稍后您可以添加保存/恢复应用程序数据和/或实现服务(听起来无论如何都要在后台下载数据)。

您不需要服务来运行后台工作线程,但是您需要 Model 单例来使用该线程检索的数据。

答案 1 :(得分:0)

您正在使用BufferedWriter,因此您正在编写" get temp"命令进入缓冲区,但缓冲区永远不会被传输,因为只有在缓冲区已满或刷新它时才会发生这种情况。

因此,简单的解决方案是消除public ActionResult Contact() { EmailFormModel model = TempData["EmailFormModel"] == null ? new EmailFormModel() : (EmailFormModel) TempData["EmailFormModel"]; ViewBag.Message = "Your contact page."; return View(model); } ,因为您需要无缓冲的通信:

BufferedWriter

另一种方法是冲出外面的作家:

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