androidloopj

Loop blocking asynchronous request from being beformed. Why and how to solve?


I define how to handle the response I receive from my server in an anonymous inner class, where I store the response in a Map to enable access from outside that inner class. Since my server call is asynchronous, I implemented a while-loop to wait for the result to be put into the map, before return it to the calling function. However, somehow my loop isn't executed (as far as I can tell at least), and the loop appear to block my request from ever being finished, which obviously leads to un endless loop.

public Login getLoginByUsername(String username)
    {
        long callID = counter.incrementAndGet();
        System.out.println("Start call");
        ServerConnection.get("myURI",null, new JsonHttpResponseHandler(){
            @Override
            public void onSuccess(int statusCode, Header[] headers, JSONObject response){
                try {

                    System.out.println("Call success, enter result:");
                    callResults.put(callID, new CallResult(Login.parseFromJson(response)));
                    System.out.println(callResults.get(callID));

                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });

        System.out.println("start waiting");
       while(callResults.get(callID) == null){
            //wait
           System.out.print(".");
        }
        System.out.println("\nwaiting over, return result:");
        System.out.println(callResults.get(callID));
        return (Login) callResults.remove(callID).content;
}

I'm sure that the request works just fine. If I remove the loop (and return null to avoid the NPE from accessing the not yet finished result), I can see from the console outputs that the request is performed and yiels a valid result after the function terminates.

I also tried to move the whole request (ServerConnection.get) to another method in case the method performing the asynchronous call must for some reason terminate for the call to be performed. This didn't help either.

Also, I never get the console output defined within the loop, so I doubt it's even executed properly...

What is happening here, and how can I fix it?


Solution

  • Upon updating the code due to the related issue/question (How to return response to calling function? (Android-App calling Java REST-Server via JSON) if you're curious), I put a thread around my request:

    public Login getLoginByUsername(String username)
        {
            long callID = counter.incrementAndGet();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    ServerConnection.get("person-login-relations?byUsername="+username,null, new JsonHttpResponseHandler(){
                        @Override
                        public void onSuccess(int statusCode, Header[] headers, JSONObject response){
                            try {
                                callResults.put(callID, new CallResult(Login.parseFromJson(response)));
                                System.out.println(callResults.get(callID));
    
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    });
    
    
                }
            })   .start();
    
            while(callResults.get(callID) == null){
                //wait
            }
            return (Login) callResults.remove(callID).content;
        }
    

    This seems to have solved the problem I decribed here of the loop blocking the request. I guess this may be because the request or the response-handling might have been handled by the same thread that contained the loop and thus was waiting for the loop to finish. I'm not entirely sure though, especiall since I was using async requests before, which have been handled in a thread outside my control