简体   繁体   中英

Retrofit Async Call Returning Null Object

I'm trying to make an async call using retrofit, but it is returning null. I was previously able to get a synchronous call to work just fine, but my async version is not working.

Here is the code where I make the call:

// 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

Here is the contents of HerokuService.java

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

I have already checked that there is internet connection, so I'm sure that is not the issue.

I also tried setting tempNodes to a dummy value inside failure but it was still null. This to me indicates that it is reaching success but that it is being set to null there.

Any thoughts on why this is happening or what I might try to fix it? Thanks!

EDIT: I tried blocking in case I wasn't waiting long enough for the callback to return as follows:

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();
}

But now it just hangs and never gets past latch.await() . Seems like the callback is just never returning?

At which point are you evaluating tempNodes? Since this is an asynchronous operation you have to wait until the callback is actually called. If you're waiting for the result anyway, leave out the callback and set the return value of nodes() to Node[] or List<Node> .

Figured it out. Seems like I'm not waiting for the callback to return before accessing tempNodes. I realized that I can block using a CountDownLatch as described here: https://stackoverflow.com/a/7735374/3399526 and then proceed after the callback finishes.

I had to use the sync version, and then run it on a seperate thread. This is the final working version:

//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();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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