我正在使用Android应用程序,该应用程序必须发出服务器请求,然后在请求完成时执行操作。这里有一些伪代码来帮助解释这种情况:
makeRequest(new SomeTask{
onDone() {
// Do actionB with queue
}
});
// Do actionA with queue. Must be execute first!!
以下是伪代码中makeRequest
的实现:
makeRequest(SomeTask task) {
if(canDoOptimization) { // if true, don't need to make request
// It's a bad idea to execute this immediately.
// Wish I could wait until the current thread of execution was done...
task.onDone();
return;
}
asyncTask = new AsyncTask<SomeTask, Void, Void>() {
doInBackground(SomeTask... task) {
// Make server request...
task.onDone();
}
}
asyncTask.execute(task);
}
通常actionA
按预期发生在actionB
之前,但在我们可以避免网络请求的情况下,会立即调用SomeTask.execute
。这会导致actionB
在 actionA
之前发生,这很糟糕。有什么方法可以保证不发生这种情况吗?
我在javascript中多次遇到过这种情况。在这些情况下,我会使用SomeTask.execute
或setTimeout
包裹setImmediate
调用,以维护正确的异步语义。
为清楚起见,以下是JavaScript中相同错误的示例:https://gist.github.com/xavi-/5882483
知道我应该在Java / Android中做些什么吗?
答案 0 :(得分:1)
欢迎来到同步世界。互斥锁或锁定对象通常用于此目的。 Is there a Mutex in Java?
你的B任务应该等待互联网完成后由任务A发出信号。这将确保正确的执行顺序,其中任务将在B之前完成。
答案 1 :(得分:1)
始终将task.onDone()
放入AsyncTask
,即使它不需要提出请求。
makeRequest(SomeTask task) {
asyncTask = new AsyncTask<SomeTask, Void, Void>() {
void doInBackground(SomeTask... task) {
if(canDoOptimization) { // if true, don't need to make request
// It's a bad idea to execute this immediately.
// Wish I could wait until the current thread of was done...
task.onDone();
return;
} else {
// Make server request...
task.onDone();
}
}
}
asyncTask.execute(task);
}
答案 2 :(得分:0)
为什么你不能只改变事物的顺序?
// Do actionA with queue. Must be execute first!!
makeRequest(new SomeTask{
onDone() {
// Do actionB with queue
});
如果actionA也是异步的并且在单独的AsyncTask上执行,你可以在actionA的AsyncTasks的onPostExecute()方法上调用makeRequest(...)。
顺便说一下,自从Android Honeycomb版本以来,AsyncTasks在同一个线程上运行,这意味着如果你有几个任务,它们可以互相阻塞。 通过指定AsyncTsak应该在线程池中运行来解决此问题:
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB) {
asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
else {
asyncTask.execute();
}