The_Martian The_Martian - 5 months ago 17
Android Question

Android global scope String returns null

I have a String declared at a class level.

String eta;


I am passing a url to a method in that same class that will use volley to retrieve distance from one of Google apis. I then assign the response String to my global variable eta. It has the needed value within the method but the global value is null when it is returned. I can't understand this behavior. What am I doing wrong here?

public String getDuration(String url){
RequestQueue queue = Volley.newRequestQueue(this);

JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST, url, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
String j = response.getString("rows");
JSONArray rowa = new JSONArray(j);
JSONObject rowobj = rowa.getJSONObject(0);
JSONArray elementsa = rowobj.getJSONArray("elements");
for (int i = 0; i < elementsa.length(); i++) {
JSONObject currentObject = elementsa.getJSONObject(i);
String duration = currentObject.getString("duration_in_traffic");
JSONObject timeObject = new JSONObject(duration);
**eta = timeObject.getString("text"); //eta has the needed value**
}
} catch (JSONException e) {
e.printStackTrace();
}
}

}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
queue.add(jsObjRequest);
**return eta; //here eta is null**
}

Answer

onResponse(JSONObject response) is asynchronous.

You are calling getDuration(String url) and setting a listener that will be called when the network operation ends. Instead of waiting the listener to be called you are returning the value (that it is not set at the moment) and that's why you get a null value.

Inside onResponse(JSONObject response) you should call the method that needs eta value.

public void getDuration(String url){
    RequestQueue queue = Volley.newRequestQueue(this);

    JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST, url, null, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            try {
                String  j = response.getString("rows");
                JSONArray rowa = new JSONArray(j);
                JSONObject rowobj = rowa.getJSONObject(0);
                JSONArray elementsa = rowobj.getJSONArray("elements");
                for (int i = 0; i < elementsa.length(); i++) {
                    JSONObject currentObject = elementsa.getJSONObject(i);
                    String duration = currentObject.getString("duration_in_traffic");
                    JSONObject timeObject = new JSONObject(duration);
                    eta = timeObject.getString("text"); //eta has the needed value**
                    methodThatUsesValue(eta);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
        }
    });
    queue.add(jsObjRequest);
}
Comments