2017-05-07 80 views
1

如何保證在Android上接連執行某個代碼?Java保證回調訂單執行

我有一個異步回調,完成,這被在另一個線程解析API查詢完成後執行,這裏是

Init() { 
    ParseQuery<ParseObject> query = ParseQuery.getQuery("MyTable"); 
    query.getInBackground("ObjectID", new GetCallback<ParseObject>() { 
     public void done(ParseObject object, ParseException e) { 
      // [ ... some code ... ] <----------. 
     } //          | 
    }); //          | 
    // I'd like this is executed after this -----' 
} 

所以,我想這個代碼,但沒有奏效,它會阻止時嘗試第二次獲取信號量

private final Semaphore available = new Semaphore(1, true); 
Init() { 
    try { 
     available.acquire(); 
     ParseQuery<ParseObject> query = ParseQuery.getQuery("MyTable"); 
     query.getInBackground("ObjectID", new GetCallback<ParseObject>() { 
      public void done(ParseObject object, ParseException e) { 
       // [ ... code ... ] 
       available.release(); 
      } 
     }); 
     available.acquire(); // waits till release 
     available.release(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 

是否因爲信號在未獲取它的線程中釋放?如何解決這個問題?

不過,我也試圖解決這個問題

private static volatile Boolean available = false; 
Init() { 
    available = false; 
    ParseQuery<ParseObject> query = ParseQuery.getQuery("MyTable"); 
    query.getInBackground("ObjectID", new GetCallback<ParseObject>() { 
     public void done(ParseObject object, ParseException e) { 
      // [ ... some code ... ] 
      available = true; 
     } 
    }); 
    while (available == false); 
} 

的這種虛擬方式,但它沒有工作循環內,它塊,回調沒有得到執行。通過刪除這一個循環回調得到執行,所以問題必須與循環有關

+0

如果你想要一個特定的訂單你爲什麼要使用異步? – EJP

回答

0

我通常使用CountDownLatch來完成。至於我可以檢查,它存在於Android的API太(here),所以你可以使用它:

Init() { 
    ParseQuery<ParseObject> query = ParseQuery.getQuery("MyTable"); 
    final taskFinishedLatch = new CountDownLatch(1); 
    query.getInBackground("ObjectID", new GetCallback<ParseObject>() { 
     public void done(ParseObject object, ParseException e) { 
      try { 
       // [ ... some code ... ] 
      } finally { 
       taskFinishedLatch.countDown(); 
      } 
     } //          | 
    }); //          | 
    taskFinishedLatch.await(); 
    // alternatively, you can use timeouts, e.g. 
    // taskFinishedLatch.await(5, TimeUnit.SECONDS); 
} 

這裏有只有一個警告:你需要確保taskFinishedLatch.countDown();被調用。這就是爲什麼我添加了try {...} finally {...}塊的原因。

在這種情況下,這是不夠的。當查詢不調用done回調時,您需要處理該案例。即是否有error回調?您可以使用時間超時,如taskFinishedLatch.await(5, TimeUnit.SECONDS),但這會使行爲有點模糊。