javaandroidandroid-volleyjsonobjectrequest

Methods aren't being called in a chronological order


I am trying to call functions in a chronological order but functions parseJSONTwo() seem to be executing before function parseJSON() (both functions just fetch JSON data from URL)

package com.example.rechev;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class pratim extends AppCompatActivity {

    RequestQueue queue;
    TextView degem;
    String model;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pratim);
        degem = findViewById(R.id.pratim);
        queue = Volley.newRequestQueue(this);
        parseJSON();
        parseJSONTwo();
    }


    public void parseJSON() {
        Intent intent = getIntent();
        int number = intent.getIntExtra("inumber", 1234567);
        String url = "http://apiurl.com" + number}";
        JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                try {
                    JSONObject result = response.getJSONObject("res");
                    JSONArray jsonArray = result.getJSONArray("rec");
                    String test = result.getString("total");

                    if (Integer.parseInt(test) == 1) {

                        for (int i = 0; i < jsonArray.length(); i++) {

                            JSONObject number = jsonArray.getJSONObject(i);

                            String carMaker = number.getString("toze");

                            degem.append(String.valueOf("\n maj: " + carMaker));

                            model = number.getString("degem_nm");

                            if (carGimur.length() >= 1) {
                                degem.append(String.valueOf("\n type: " + carGimur));
                            }
                        }
                    } else {
                        degem.append("invalid");
                    }
                } catch (JSONException e) {
                    degem.append(e.toString());
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                degem.append("Error");
            }
        });

        queue.add(request);
    }


    public void parseJSONTwo() {
        String url = "http://apiurl.com"+model}";
        JsonObjectRequest requestt = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                try {
                    JSONObject result = response.getJSONObject("res");
                    JSONArray jsonArray = result.getJSONArray("rec");
                    String test = result.getString("total");

                    if (Integer.parseInt(test) == 1) {

                        for (int i = 0; i < jsonArray.length(); i++) {

                            JSONObject number = jsonArray.getJSONObject(i);

                            String carNefah = number.getString("nefah_manoa");

                            degem.append(String.valueOf("num: " + carNefah));
                         }
                    }
                } catch (JSONException e) {
                    degem.append(e.toString());
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                degem.append("Error");
            }
        });

        queue.add(requestt);
    }
}


the function parseJSON() fetches JSON data from url and puts it into a TextView, And it also sets a global variable (model) a value, which parseJSONTWO() uses in its URL so it can fetch data based on the first parseJSON() function.

The problem is parseJSONTwo() is being called first for some reason, so it can't use the information parseJSON() retrieves.

Updated code:

package com.example.rechev;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class pratim extends AppCompatActivity {

    RequestQueue queue;
    TextView degem;
    String model;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pratim);
        degem = findViewById(R.id.pratim);
        queue = Volley.newRequestQueue(this);
        parseJSON();

    }


    public void parseJSON() {
        Intent intent = getIntent();
        int number = intent.getIntExtra("inumber", 1234567);
        String url = "http://apiurl.com" + number}";
        JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                try {
                    JSONObject result = response.getJSONObject("res");
                    JSONArray jsonArray = result.getJSONArray("rec");
                    String test = result.getString("total");

                    if (Integer.parseInt(test) == 1) {

                        for (int i = 0; i < jsonArray.length(); i++) {

                            JSONObject number = jsonArray.getJSONObject(i);

                            String carMaker = number.getString("toze");

                            degem.append(String.valueOf("\n maj: " + carMaker));

                            model = number.getString("degem_nm");

                            if (carGimur.length() >= 1) {
                                degem.append(String.valueOf("\n type: " + carGimur));
                            }
                        }
                    } else {
                        degem.append("invalid");
                    }

                  if(model.length() >= 1){
                      parseJSONTwo();
                   }
                } catch (JSONException e) {
                    degem.append(e.toString());
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                degem.append("Error");
            }
        });

        queue.add(request);
    }


    public void parseJSONTwo() {
        String url = "http://apiurl.com"+model}";
        JsonObjectRequest requestt = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                try {
                    JSONObject result = response.getJSONObject("res");
                    JSONArray jsonArray = result.getJSONArray("rec");
                    String test = result.getString("total");

                    if (Integer.parseInt(test) == 1) {

                        for (int i = 0; i < jsonArray.length(); i++) {

                            JSONObject number = jsonArray.getJSONObject(i);

                            String carNefah = number.getString("nefah_manoa");

                            degem.append(String.valueOf("num: " + carNefah));
                         }
                    }
                } catch (JSONException e) {
                    degem.append(e.toString());
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                degem.append("Error");
            }
        });

        queue.add(requestt);
    }
}


now parseJSONTwo will get the correct URL but will not complete the function.


Solution

  • In each of those functions, parseJSON() and parseJSONTWO(), you're making asynchronous network requests. A network request is not immediate, taking anywhere from a few milliseconds to tens of milliseconds which is much slower than your program executes. Since the network requests take some time to resolve the corresponding onResponse() functions are also delayed and fire when the related requests return.

    Thus, the order of operations in your code is

    1. call parseJSON() which starts a GET request that make take a while
    2. call parseJSONTwo() which starts another GET request without waiting on the response from the GET request of parseJSON() and that may take a while as well

    The function parseJSONTwo() is called immediately after the function parseJSON() returns after starting the GET request, which may not yet have completed since the GET request may take a while. So the GET request of parseJSON() may still be in process and without a response when the function parseJSONTwo() is called to start the next GET request.

    When each of the requests returns, its onResponse() callback will fire. However the order that they return is not specified. It will depend on the server and network conditions and how long each request takes to be completed.

    And since the function parseJSONTwo() requires the response of the function parseJSON(), you have to chain these functions so that the second function, parseJSONTwo() is called only when the response of the first function's GET request is received.

    One way to chain these functions is to call the function parseJSONTwo() in the OnResponse() handler of the function parseJSON().