繁体   English   中英

Java保证回调订单执行

[英]Java guarantee callback order execution

我如何保证在Android上执行某个代码?

我有一个异步回调,完成,在Parse 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);
}

但它不起作用,它在循环内部阻塞,并且回调不会被执行。 通过删除此循环中的循环,将执行回调,因此问题必须与循环相关

我通常使用CountDownLatch来做。 据我所知,它也存在于Android API中( 这里 ),所以你可以使用它:

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)等时间超时,但这会使行为有点模糊。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM