我一直在寻找我的问题的答案,但到目前为止没有一个解决方案帮助我解决它。我正在开发一个与另一个用作服务器的设备通信的应用程序。该应用程序向服务器发送查询并接收适当的响应以动态创建片段。
在第一个实现中,app发送了查询,然后等待在单个线程中接收答案。但该解决方案并不令人满意,因为该应用程序未收到服务器的任何反馈。服务器管理员说他正在接收查询,但他暗示该设备发送回答的速度太快,并且应用程序在答案到达时可能还没有收听。
所以我想要实现的是创建单独的线程:一个用于监听,一个用于发送查询。在我们向服务器发送任何内容之前,侦听的内容将启动,以确保应用程序不会错过服务器响应。
到目前为止,实现这一点并不成功。我已经尝试编写并运行单独的Runnable类和AsyncTasks,但是侦听器从未收到过答案,并且在某些时候其中一个线程甚至没有执行。以下是asynctask侦听器的代码:
@Override
protected String doInBackground(String... params) {
int bufferLength = 28;
String masterIP = "192.168.1.100";
try {
Log.i("TCPQuery", "Listening for ReActor answers ...");
Socket tcpSocket = new Socket();
SocketAddress socketAddress = new InetSocketAddress(masterIP, 50001);
try {
tcpSocket.connect(socketAddress);
Log.i("TCPQuery", "Is socket connected: " + tcpSocket.isConnected());
} catch (IOException e) {
e.printStackTrace();
}
while(true){
Log.i("TCPQuery", "Listening ...");
try{
Log.i("TCPQuery", "Waiting for ReActor response ...");
byte[] buffer = new byte[bufferLength];
tcpSocket.getInputStream().read(buffer);
Log.i("TCPQuery", "Received message " + Arrays.toString(buffer) + " from ReActor.");
}catch(Exception e){
e.printStackTrace();
Log.e("TCPQuery", "An error occured receiving the message.");
}
}
} catch (Exception e) {
Log.e("TCP", "Error", e);
}
return "";
}
这就是调用任务的方式:
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB) {
listener.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "");
sender.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "");
}
else {
listener.execute();
sender.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
你究竟会如何解决这个问题?如果这段代码不够用,我很乐意发布更多内容。
答案 0 :(得分:1)
这是因为Android的AsyncTask
实际上只是一个线程,无论你创建多少个,所以如果你真的想要同时运行两个线程,我建议你使用标准的Java并发包工具,而不是{ {1}}。正如in the documentation所述:
AsyncTask旨在成为Thread和Handler的辅助类 并不构成通用的线程框架。 AsyncTasks 理想情况下应该用于短期操作(几秒钟的时间) 大多数。)如果你需要保持线程长时间运行, 强烈建议您使用提供的各种API java.util.concurrent pacakge ,例如Executor,ThreadPoolExecutor和 FutureTask。
答案 1 :(得分:0)
看这是tcp连接。所以你不需要为数据丢失而烦恼。这是端口到端口的连接,它永远不会发送流的结束(-1)。也许你必须关心阅读功能。因为你不能顺应所有接受的蒸汽。 Tcp读取方法是阻塞调用。如果您的读缓冲区大小小于可用的流大小,则它将阻塞,直到它可以完全读取。并且您使用的是Android设备,可能的流可能会因您的设备网络而异。所以你有2个选择, 1)您的缓冲区大小应该是动态的。首先使用is.available()检查可用的输入流大小,然后按此大小创建buf大小。如果可用大小为零,则休眠一段时间以检查它是否丢失了其流可用性。 2)设置输入流超时。它确实有效,因为它读取其可用流并等待超时延迟,如果任何流在超时期限内不可用,则它会抛出超时异常。 尝试更改您的代码。