1

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?

0

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

9 Comments

I'm evaluating where I left the comment indicating so. But I'm guessing you're right that the callback hasn't returned by then. Is there a way that I can block until it returns?
And also, I did already try a synchronous call as you suggested and it worked fine. I'm trying to use an async call specifically here.
Use a semaphore or some other synchronization mechanism. To be honest, this would defeat the purpose of asynchronous callbacks, though.
Yes, I do realize that. For now I'm just trying to implement this asynchronously for the sake of doing so :)
Hold on a minute. This is still not working. Now the callback is just never returning and it's blocking forever. Any idea why the callback might not be returning?
|
1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.