我正在使用
的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);
}
答案 0 :(得分:2)
while (!socket.isConnected() ...
问题出在这里。无论如何,测试毫无意义,因为它永远不会是错误的,但否定它意味着受控块永远不会执行。只需删除isConnected()
测试。
当它无法读取时,它将返回null并且循环将继续运行。
因为你没有正确处理这个案子。如果line
为null,则必须退出循环并关闭连接。通常的写法是:
String line;
while ((line = reader.readLine()) != null)
{
// ...
}
你在你的循环中睡觉只是浪费时间。
答案 1 :(得分:0)
试试这个
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/