2

I have this android code which bring a JSON from a server and fill an ArrayList from that JSON I checked the size of the ArrayList "meals" inside the onresponse void it gives me 1 but when i check it after the StringRequest object i get 0 items . meals is defined in global scope and initialized inside the oncreateview function The Code:

               public View onCreateView(LayoutInflater inflater, ViewGroup container,  Bundle savedInstanceState) {
// Inflate the layout for this fragment
Log.i("debug","on create view");
View view =inflater.inflate(R.layout.fragment_meal_list,container,false);
ListView List ;
meals=new ArrayList<meal>();
String url="http://syriankitchen.tk/get_recent.php";
StringRequest mealsrequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {

    @Override
    public void onResponse(String response) {
        try{
            JSONObject object= new JSONObject(response);
            JSONArray mealsArray = object.getJSONArray("result");
            for(int i=0;i<mealsArray.length();i++){
                JSONObject cur = mealsArray.getJSONObject(i);
                int id= cur.getInt("id");
                String name= cur.getString("name");
                String description = cur.getString("description");
                int price = cur.getInt("price");
                meals.add(new meal(id,name,price,description));
            }
            Log.i("debug","meals size = "+meals.size());
        }
        catch(JSONException e){
            e.printStackTrace();
        }
    }
},new Response.ErrorListener(){
    @Override
    public void onErrorResponse(VolleyError error) {
        Toast.makeText(getActivity(),error.getMessage(),Toast.LENGTH_SHORT).show();
    }
});
Volley.newRequestQueue(getActivity()).add(mealsrequest);
ArrayList<String> strs=new ArrayList<String>();
String mealsnames[]=new String[meals.size()];
for(int i=0;i<meals.size();i++)strs.add(meals.get(i).getName());
strs.toArray(mealsnames);
Log.i("debug","meals ou size "+meals.size());
CustomList  adapter = new CustomList(getActivity(),mealsnames,meals);
List = (ListView)view.findViewById(R.id.list);
List.setAdapter(adapter);
1
  • you are confused as to what after means. callbacks are asynchronous. Commented Apr 21, 2016 at 18:26

2 Answers 2

6

The problem here is about understanding how asynchronous tasks work. When you are adding a volley request to the queque, it will run in background thread (off the main thread) and control will pass to the next line.

So, after this:

Volley.newRequestQueue(getActivity()).add(mealsrequest);

control passes to this:

ArrayList<String> strs=new ArrayList<String>();
String mealsnames[]=new String[meals.size()];

Now since meals is updated on the background thread, you are not able to get the data by the time control reaches String mealsnames[]=new String[meals.size()];

So you will get zero size (meals.size()) here.

Try to move this portion of the code into onResponse.

Try like this:

public void updateData(){
   ArrayList<String> strs=new ArrayList<String>();
   String mealsnames[]=new String[meals.size()];
   for(int i=0;i<meals.size();i++)strs.add(meals.get(i).getName());
   strs.toArray(mealsnames);
   Log.i("debug","meals ou size "+meals.size());
   CustomList  adapter = new CustomList(getActivity(),mealsnames,meals);
   List = (ListView)view.findViewById(R.id.list);
   List.setAdapter(adapter);
}

and call this method from onResponse:

@Override
public void onResponse(String response) {
    try{
        JSONObject object= new JSONObject(response);
        JSONArray mealsArray = object.getJSONArray("result");
        for(int i=0;i<mealsArray.length();i++){
            JSONObject cur = mealsArray.getJSONObject(i);
            int id= cur.getInt("id");
            String name= cur.getString("name");
            String description = cur.getString("description");
            int price = cur.getInt("price");
            meals.add(new meal(id,name,price,description));
        }
        Log.i("debug","meals size = "+meals.size());
        updateData();
    }
    catch(JSONException e){
        e.printStackTrace();
    }
}
Sign up to request clarification or add additional context in comments.

Comments

2

When you write this -

Volley.newRequestQueue(getActivity()).add(mealsrequest);

That means you are making an asynchronous call and that mealsrequest will run on another thread. You are printing -

Log.i("debug","meals ou size "+meals.size());

just after you make your mealsrequest. When control reaches this statement your network request is not completed yet. So apparently, you don't have anything in your list. Your list will be populated in onResponse() only, since that method is executed after the network request gets completed.

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.