[英]Best way to guarantee a callback is always executed asynchronously?
我正在使用一個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
之前 actionA
,這是不好的。 有什么辦法可以保證不會發生這種情況嗎?
我在javascript中多次遇到這種情況。 在這些情況下,我將使用setTimeout
或setImmediate
包裝SomeTask.execute
調用以維護適當的異步語義。
為了清楚起見,下面是JavaScript中相同錯誤的示例: https : //gist.github.com/xavi-/5882483
知道我應該在Java / Android中做什么嗎?
歡迎來到同步世界。 互斥鎖或鎖定對象通常用於此目的。 Java中是否有Mutex?
您的B任務應等待互斥量,而互斥量將在任務A完成時發出信號。 這將確保正確的執行順序,其中A任務將在B之前完成。
始終將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);
}
您為什么不能只切換事物順序?
// 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();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.