2017-05-07 60 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),但这会使行为有点模糊。