1

I am trying to get information from my AsyncHttpClient in my Android app, and I need to use an interface to set the variable so I can use it in my main method. However, when I run System.out.println(PostResponse);, I am getting null.

I don't understand why, because if I put the line in my callback() method, I get the values.

From my main method:

try {
    JSONArray PostResponse = PerformPostRequest(new OnJSONResponseCallback() {
        @Override
        public JSONArray onJSONResponse(boolean success, JSONArray response) {
            System.out.println("Response: " + response);  //This is returning the correct value

            return response;
        }
    }, PostData);

    System.out.println("Useable: " + PostResponse); //This is returning null.
} catch (Exception e) {
    e.printStackTrace();
}

The interface:

public interface OnJSONResponseCallback {
    public JSONArray onJSONResponse(boolean success, JSONArray response);
}

The AsyncHttpClient:

public JSONArray PerformPostRequest(final OnJSONResponseCallback callback, JSONObject PostData) {
    //To authenticate against the API we need the user's credentials
    String Email = getSharedPreferences(ctx).getString("Email","");
    String Password = getSharedPreferences(ctx).getString("Password","");

    final JSONArray[] ResponseStorage = new JSONArray[1];

    //Add the credentials to post data
    try{
        PostData.put("email", Email);
        PostData.put("password", Password);
    } catch (Exception e){
        e.printStackTrace();
    }

    //Then we need to put the post data into request parameters so we can send them in the call.
    RequestParams RequestParameters = new RequestParams();
    RequestParameters.put("data", PostData);

    //This is the client we will use to make the request.
    AsyncHttpClient client = new AsyncHttpClient();

    client.post(AppHost + "MyMeetings.php", RequestParameters, new AsyncHttpResponseHandler() {
        @Override
        public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
            try {
                String ResponseString = new String(responseBody);
                ResponseStorage[0] = new JSONArray(ResponseString);
                System.out.println(ResponseStorage[0] + "<=============");  //Returns with the array
                callback.onJSONResponse(true, ResponseStorage[0]);
            } catch (Exception e) {
                Log.e("Exception", "JSONException on success: " + e.toString());
            }
        }

        @Override
        public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
            try {
                Toast.makeText(ctx, "Error: " + statusCode, Toast.LENGTH_LONG).show();
            } catch (Exception e) {
                Log.e("Exception", "JSONException on failure: " + e.toString());
            }
        }
    });

    JSONArray ResponseArray = new JSONArray();

    try{
        System.out.println(ResponseStorage[0] + "<==============="); //Returning null?
        ResponseArray = ResponseStorage[0];
    } catch (Exception e){
        e.printStackTrace();
    }

    System.out.println("ResponseArray" + ResponseArray); //Returns null
    return ResponseArray;
}

Where am I going wrong? I think it is something to do with my call in the main method.

Edit:

1) I tried to return the ResponseArray (set in onsuccess) but I can't return it from onsuccess because it is public void. When I tried to change it to public JSONArray, I get an incompatible return type error.

2) I have updated the method so it returns something other than null, however, it still returns as null, even when I am printing it inside the AsyncHttp.

4
  • 2
    my guess, you are trying to process your response before it is actually returned. Commented Feb 12, 2018 at 10:22
  • 4
    The last line of PerformPostRequest is return null;. Commented Feb 12, 2018 at 10:24
  • It returns null because you told it to. There is only one return statement, and it returns null. Commented Feb 12, 2018 at 10:26
  • I tried to return the ResponseArray (set in onsuccess) but I can't return it from onsuccess because it is public void. When I tried to change it to public JSONArray, I get an incompatible return type error. Commented Feb 12, 2018 at 10:28

2 Answers 2

2

The general idea behind the asynchronous calls is that:

  • the asynchronous method call (in your case PerformPostRequest) returns immediately and does not return the expected result - instead it returns either just an accept confirmation or an object from which you can sometimes in the future get the result (such as an instance of a Future)

  • you provide the method a callback interface (in your case OnJSONResponseCallback) or the method returns an instance of a callback interface, and you check regularly if there is already a result ready.

You should not expect that the asynchronous method returns the result immediately, this is exactly the opposite of asynchronous call.

Here is the rough idea expressed by pictures. It is just an overall picture of the whole idea, so the implementation details may be quite different!

Synchronous method call

Asynchronous method call - A

Asynchronous method call - B

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

Comments

0

I was trying to set the variable from the PerformPostRequest(), which by default does not get called. At the top of my class, I set a

public JSONArray[] PostResponse = new JSONArray[1];

and updated the bit where I was calling the post request to the following:

//Make a post request
try {
    JSONObject PostData = new JSONObject();
    PostData.put("action","test");
    PerformPostRequest(new OnJSONResponseCallback(){
        @Override
        public JSONArray onJSONResponse(boolean success, JSONArray response) {
            PostResponse[0] = response;
            System.out.println(PostResponse[0]); //This will be replaced by calling the method I want to call.
            return PostResponse[0];
        }
    }, PostData);
    System.out.println(PostResponse[0]);
} catch (Exception 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.