我正在开发一个与其他设备通信的Android应用程序,就像服务器一样。基本上要构建应用程序的视图,我首先必须通过TCP连接向服务器发送查询以获取信息。我(成功)在异步任务的帮助下执行这些查询:
private class TCPQuery extends AsyncTask<String, String, String> {
@Override
protected String doInBackground(String... params) {
//connect the socket send the query and receive feedback
}
@Override
protected void onPostExecute(String result) {
//parse server feedback and build the view
}
}
这种方法适用于单个查询,这些查询在应用程序的生命周期内只进行了几次。我在实施方面遇到的问题如下: 应用程序中的某个视图,包含搜索栏。所以基本上,每次更改seekbar值(每次onProgressChange方法触发)都必须发送到服务器(这次没有反馈),所以它可以跟踪实际值。
你将如何实现这一目标?当然,在主线程上可能没有在android中建立联网。但是,这里建立连接,每次值更改时发送消息和关闭连接都是不可接受的。只是稍微滑动一下吧就会导致十几次这样的调用。
我已尝试通过实施服务来解决此问题。该服务有自己的套接字与服务器通信。我将套接字连接到服务器并保持打开状态,这样我就可以在任何时候进行搜索条更改时调用服务的send方法。但这似乎干扰了我之前提到的其他查询(使用异步任务执行的查询)。当另一个活跃时,我无法连接一个。现在我不确定我的服务实现是不是很糟糕,或者我是否误解了一个关键的网络概念。
我曾想过只在onStopTrackingTouch上发送数据,但这并不是我所追求的。非常感谢任何帮助!
答案 0 :(得分:0)
使用系统时钟检查上次查询的发送时间,并且在经过一定时间后才发送另一个查询。 您可以根据需要更改搜索栏的值,但查询将仅每隔X毫秒发送一次。
static long sendInterval = 600; //milliseconds
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
long nextSend = 0;
}
@Override
public void onProgressChanged(......) {
if (nextSend < uptimeMillis()) {
...send the query and parse feedback...
nextSend = uptimeMillis() + sendInterval ;
}
从nextSend = 0开始,所以第一次立即发送查询。 根据服务器的响应时间选择sendInterval值。从较高的值开始并减少,直到您看到一切正常。 如果查询本身和响应很小(几个字节),请考虑使用UDP而不是TCP,它会更快,您可以使用较低的sendInterval值。
答案 1 :(得分:0)
其他方式,不同,也许更好: 由于响应时间可能因网络流量,查询复杂性和服务器负载而有很大差异,因此您可以使用布尔标志。在发送查询之前将其设置为False,在解析响应后将其设置为True。在If语句中使用它:
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
boolean readyForQuery = true;
}
@Override
public void onProgressChanged(......) {
if (readyForQuery) {
readyForQuery = false;
<...asyncronous send the query, parse feedback and set readyForQuery=true;...>
}
还要考虑最坏的情况:当服务器关闭时,根本不会对查询做出响应。 注意找到一种方法,在合理的时间后和/或查询代码生成异常时将标志设置为True,否则即使服务器再次启动也不会得到进一步的响应。