每次按下按钮和释放按钮时,我都会发送一个http post。在释放按钮之前,我很可能不会收到“按下”帖子的响应,因此我尝试同时运行这些任务。但是,有时,释放按钮的post请求会在请求按下按钮之前发送到服务器。我怎样才能避免/解决这个问题?
button = (ImageButton) findViewById((R.id.button1));
button.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
HTTPAsyncTask task = new HTTPAsyncTask();
if (event.getAction() == MotionEvent.ACTION_DOWN ) {
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, Utilities.StringCollection.rotateRight);
return true;
}
else if (event.getAction() == MotionEvent.ACTION_UP){
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, Utilities.StringCollection.stop);
return true;
}
return false;
}
});
2条答案
按热度按时间ifsvaxew1#
从概念上讲,你的
HTTPAsyncTask
doInBackground()
由两个不同的操作组成:连接,并将请求排队到套接字
接收响应
(当然,在那之后,
onPostExecute()
将被调用。)如前所述,您需要控制操作1在两个不同线程上的执行顺序,同时允许操作2并行执行。
这不可能使用泛型
AsyncTask
机制,因为您没有提供任何“将任务一分为二”的方法;线程a无法判断线程b何时从操作1切换到操作2,反之亦然。可以添加这样的逻辑,但是您没有解释如何进行套接字调用。
但是,提供这些额外的细节没有什么意义;与网络请求相关联的边缘案例会破坏您可能拥有的任何订单保证。网络有损;请求可能失败,响应可能失败。即使请求是按顺序发送的(特别是在使用两个单独的套接字时),请求也可能会按顺序到达。自动重试可能需要几秒钟才能完成。
瞧,“按下”的请求可能会被网络丢失,在“未按下”的请求完成后,您可能需要将其重新排队到套接字。
我建议您放弃正在寻求的“部分条件并发”,只需确保
HTTPAsyncTask
在执行第二个之前已完成。或者,您可以向每个post添加一个连续的“request id”,或者在第二个请求中包含关于第一个请求的信息,这样服务器就可以整理出发生了什么,即使请求到达的顺序不对。
xbp102n02#
如果您的min sdk是11“honeycomb”,您可以像这样调用asynctask以在单线程中运行它,以防止它们之间出现争用情况:
重要提示:网络i/o不可靠,网络包可能丢失或无法按发送顺序接收,但我看到了标题中的问题
“android中的两个并发异步任务-如何处理竞争条件?”
就这么回答了。因此,您无法确定是否以这种方式一个接一个地接收到请求。我建议您在一个请求中向服务器发送两个事件,并在服务器中分析它。