[英]Android : Keep socket open to read message from server
我正在开发一个Android应用程序
所以,我创建了一个线程子类来执行此操作
public class ServerThread extends Thread {
public interface OnReadListener {
public void onRead(ServerThread serverThread, String response);
}
Socket socket;
String address;
int port;
OnReadListener listener = null;
public ServerThread(String address, int port) {
this.address = address;
this.port = port;
}
@Override
public void run() {
try {
socket = new Socket(InetAddress.getByName(address), port);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
PrintWriter writer = new PrintWriter(bw, true);
writer.println("*99*1##");
writer.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line;
while (!socket.isConnected() && !Thread.currentThread().isInterrupted()) {
line = br.readLine();
if (line != null) {
Log.i("Dev", "Line ")
if (listener != null) {
listener.onRead(this, line);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void setListener(OnReadListener listener) {
this.listener = listener;
}
}
在活动中,我这样做
public class MainActivity extends Activity {
ServerThread st = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
}
@Override
public void onResume() {
startMonitoring();
super.onResume();
}
@Override
public void onPause() {
stopMonitoring();
super.onPause();
}
private void startMonitoring() {
stopMonitoring();
st = new ServerThread(SERVER_IP_ADDRESS, SERVER_PORT);
st.setListener(new OnReadListener{
@Override
public void onRead(ServerThread serverThread, String response) {
runOnUiThread(new Runnable() {
@Override
public void run() {
// update UI or do something with response
}
})
}
});
st.start();
}
private void stopMonitoring() {
if (st != null) {
st.stop();
st = null;
}
}
}
在我开始这项活动后,我发现了这一点
我不知道如何做这项工作。 欢迎任何建议。
您可能需要了解一些注意事项
我不确定BufferReader是否是我需要的正确对象。 因为当它无法读取时,它将返回null并且循环将继续运行。 我可能需要一些可以冻结线程等待输入的对象。 只要服务器可以在几秒,几分钟,几小时或更长时间内发送消息,该对象就可以等待输入。 收到消息后,继续执行代码并转到下一轮循环。
(我是全职的iOS开发人员,不熟悉Java)
最终编辑
在仔细检查代码后,我发现了我犯的愚蠢错误
writer.println("*99*1##")
基本上,println将发送“* 99 * 1 ##”,然后使用换行符 。 但我的硬件服务器不喜欢它,所以它终止连接。 这就是我从BufferReader的readLine()得到null的原因。
我换了之后
writer.print("*99*1##")
服务器收到“* 99 * 1 ##”并保持连接。 然后,我可以循环阅读响应,就像EJP再次建议一样
String line;
while ((line = br.readLine()) != null) {
if (listener != null) {
listener.onRead(this, line);
}
}
if (listener != null) {
listener.onTerminated(this);
}
while (!socket.isConnected() ...
问题出在这里。 无论如何,测试毫无意义,因为它永远不会是错误的,但否定它意味着受控块永远不会执行。 只需删除isConnected()
测试即可。
当它无法读取时,它将返回null并且循环将继续运行。
因为你没有正确处理这种情况。 如果line
为null,则必须退出循环并关闭连接。 通常的写法是:
String line;
while ((line = reader.readLine()) != null)
{
// ...
}
你在你的循环中睡觉只是浪费时间。
尝试这个
while (isRunning) {
line = br.readLine();
if (line != null) {
Log.i("Dev", "Line ")
if (listener != null) {
listener.onRead(this, line);
}
}
}
注意:isRunning是一个布尔变量,用于控制线程生命周期。 每当你想要停止这个线程时,设置isRunning = false
并在你的连接上调用close()
。
如果要创建TCP服务器,则应使用ServerSocket
而不是Socket
。 这是关于socket
java文档,但android使用相同的http://docs.oracle.com/javase/tutorial/networking/sockets/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.