Himanshu Babal
Himanshu Babal

Reputation: 645

Execute the method after volley response is received

When I run the following code, I get "blank" in the log, whereas I want it 'volleyResult' to be set to the response generated by volley request.

However when I run same code for second time, it shows correctly.

So, How to hold "Log.i(--)" in 'courses' method to execute until the volleyResult has arrived.

I have several methods just like 'courses', the only difference between them is the URL which they call. Also they all are serving as 'OnButtonClickListner', so calling 'courses' inside 'req' isn't an option.

    String volleyResult = "blank";

    public void courses(View view) {
        String url = "http://courses/list.json";
        reqReturn(url, "Courses");
        Log.i("Volley Res", volleyResult);    
    }


    public void req(String url, final String type ) {

    StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    volleyResult = response;
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            volleyResult = "error";
        }
    }) {
        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            HashMap<String, String> headers = new HashMap<String, String>();
            headers.put("Cookie", cookie);
            return headers;
        }
    };
    queue.add(stringRequest);

    }

Upvotes: 4

Views: 4882

Answers (3)

Bj&#246;rn Kechel
Bj&#246;rn Kechel

Reputation: 8463

call courses() in onResponse()

Edit to clarify:

You fill the var volleyResult within your Response.Listener. This is asynchronous and the time it takes depends on the server delay and your internet connection. There are several ways to "hold" out your processing method that needs the result in volleyResult.

The easiest way: Move the process (in your case the Log.i("Volley Res", volleyResult); within the onResponse method, after you store the response in volleyResult.

A bit cleaner: Move the your code into a new function and call it from your Response.Listener methods:

@Override
public void onResponse(String response) {
  volleyResult = response;
  methodToHoldUntilResponseArrived();
}

public void methodToHoldUntilResponseArrived(){
  // your code that relies on the volley response
  Log.i("Volley Res", volleyResult);
}

In case your courses method gets called repeatedly anyways: You could set a flag when the data is received and place your code within courses() in an if-condition block:

private boolean mHasReceivedData = false;
@Override
public void onResponse(String response) {
  volleyResult = response;
  mHasReceivedData = true;
}

public void courses(View view){
  // your code that relies on the volley response
  if(mHasReceivedData){
        Log.i("Volley Res", volleyResult);
  }
}

Upvotes: 2

Chandan kushwaha
Chandan kushwaha

Reputation: 951

Print the LOG on the OnResponse() method. Also again call the Same API if Time Out Error occurs in the OnErrorResponse() method.

Upvotes: 0

Nadir
Nadir

Reputation: 1819

Easyway - Put Log.i() inside the onResponse method

Other option is to use wait()/notify(). You would need a monitor object to hanlde everything.

 public synchronized void courses(View view) {
    String url = "http://courses/list.json";
    reqReturn(url, "Courses");
    wait();
    Log.i("Volley Res", volleyResult);    
}

And in onResponse

public void onResponse(String response) {
                volleyResult = response;
                YourClass.this.notify();
            }

Upvotes: 0

Related Questions