改进异步调用返回空对象

时间:2014-07-13 14:18:38

标签: java android asynchronous null retrofit

我正在尝试使用改造进行异步调用,但它返回null。我以前能够获得同步调用才能正常工作,但我的异步版本无效。

以下是我拨打电话的代码:

// Get the nodes from Heroku
RestAdapter restAdapter = new RestAdapter.Builder().setEndpoint(
        "http://myURL.com").build();
HerokuService herokuService = restAdapter.create(HerokuService.class);
Callback<Node[]> callback = new Callback<Node[]>()
{
    @Override
    public void failure(RetrofitError err)
    {
    }

    @Override
    public void success(Node[] nodeArray, Response response)
    {
        tempNodes = nodeArray;
    }
};
herokuService.nodes(callback);
// tempNodes is null here

以下是HerokuService.java

的内容
public interface HerokuService
{
    @GET("/nodes")
    void nodes(Callback<Node[]> callback);
}

我已经检查过网络连接,所以我确定这不是问题。

我还尝试将tempNodes设置为failure内的虚拟值,但它仍然为空。这对我来说表明它已达到success但在那里被设置为空。

对于为什么会发生这种情况或者我可能会尝试修复它的任何想法?谢谢!

编辑:我试过阻止以防万一我没有等待回调的时间如下:

CountDownLatch latch = new CountDownLatch(1); //Class variable

//...

Callback<Node[]> callback = new Callback<Node[]>()
{
    @Override
    public void failure(RetrofitError err)
    {
        latch.countDown();
    }

    @Override
    public void success(Node[] nodeArray, Response response)
    {
        tempNodes = nodeArray;
        latch.countDown();
    }
 };
herokuService.nodes(callback);
try
{
    latch.await();
}
catch (InterruptedException e)
{
    e.printStackTrace();
}

但现在它只是挂起而且永远不会超过latch.await()。好像回调永远不会回来?

2 个答案:

答案 0 :(得分:1)

您在哪个时候评估tempNodes?由于这是异步操作,因此必须等到实际调用回调。如果您仍在等待结果,请忽略回调并将nodes()的返回值设置为Node[]List<Node>

答案 1 :(得分:1)

想出来。看起来我在等待访问tempNode之前没有等待回调。我意识到我可以阻止使用如下所述的CountDownLatch:https://stackoverflow.com/a/7735374/3399526然后在回调结束后继续。

我必须使用同步版本,然后在单独的线程上运行它。这是最终的工作版本:

//Get the nodes from heroku, and block until we get them
final CountDownLatch latch = new CountDownLatch(1);
Thread thread = new Thread(new Runnable()
{
    @Override
    public void run()
    {
        try
        {
            // Get the nodes from Heroku
            RestAdapter restAdapter = new RestAdapter.Builder()
                    .setEndpoint("http://safe-hollows-9286.herokuapp.com")
                    .build();
            HerokuService herokuService = restAdapter.create(HerokuService.class);
            tempNodes = herokuService.nodes();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        latch.countDown();
    }
});
thread.start();
try
{
    latch.await();
}
catch (InterruptedException e)
{
    e.printStackTrace();
}