[英]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,这只会使重现此行为更加困难)。
从MVC ( Model-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.