How to put JSON api data to recyclerview using Volley library in java?

Issue

I am trying to put JSON api data to recyclerview using volley library. My Api urlhere

But it gives this error,my logcat :-

    java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference
        at com.example.test2.MainAdapter.getItemCount(MainAdapter.java:48)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:4044)
        at androidx.recyclerview.widget.RecyclerView.onMeasure(RecyclerView.java:3534)
        at android.view.View.measure(View.java:18855)
        at android.widget.ScrollView.measureChildWithMargins(ScrollView.java:1283)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at android.widget.ScrollView.onMeasure(ScrollView.java:340)
        at android.view.View.measure(View.java:18855)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6107)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
        at android.view.View.measure(View.java:18855)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6107)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:145)
        at android.view.View.measure(View.java:18855)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6107)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
        at android.view.View.measure(View.java:18855)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6107)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at android.view.View.measure(View.java:18855)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6107)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
        at android.view.View.measure(View.java:18855)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6107)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at com.android.internal.policy.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2798)
        at android.view.View.measure(View.java:18855)
        at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2119)
        at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1235)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1471)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1126)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6098)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:892)
        at android.view.Choreographer.doCallbacks(Choreographer.java:704)
        at android.view.Choreographer.doFrame(Choreographer.java:640)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:878)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:5541)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:853)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:737)

My Activity(test)

public class test extends AppCompatActivity {

    RecyclerView recyclerView;
    ArrayList<MainData> dataArrayList;
    MainAdapter adapter;
    RequestQueue requestQueue;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);

        recyclerView  findViewById(R.id.recycler_view);

        adapter  new MainAdapter(dataArrayList,test.this);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setAdapter(adapter);
        dataArrayList  new ArrayList<>();
        requestQueue  Volley.newRequestQueue(this);

        parseJson();
    }

    private void parseJson() {


        String url  "http://quran-endpoint.herokuapp.com/quran/18/";
        JsonObjectRequest jsonObjectRequest  new JsonObjectRequest(Request.Method.GET, url,null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                try {
                    JSONObject data  response.getJSONObject("data");
                    JSONArray ayah  data.getJSONArray("ayahs");
                    for (int i  0; i < response.length(); i++){
                        JSONObject ayahs  ayah.getJSONObject(i);
                        JSONObject text  ayahs.getJSONObject("text");
                        JSONObject translation  ayahs.getJSONObject("translation");

                        String arabic  text.getString("ar");
                        String english  text.getString("read");
                        String trans  translation.getString("read");
                        dataArrayList.add(new MainData(english, arabic, trans));
                        adapter  new MainAdapter(dataArrayList, test.this);
                        recyclerView.setAdapter(adapter);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        });
        requestQueue.add(jsonObjectRequest);
        requestQueue.getCache().clear();

    }
}

My Adapter(MainAdapter)

public class MainAdapter extends RecyclerView.Adapter<MainAdapter.ViewHolder>{

    ArrayList<MainData> dataArrayList;
    Context activity;

    public MainAdapter(ArrayList<MainData> dataArrayList, Context activity) {
        this.dataArrayList  dataArrayList;
        this.activity  activity;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) {

        View view  LayoutInflater.from(activity)
                .inflate(R.layout.list_row_main,parent,false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull @NotNull MainAdapter.ViewHolder holder, int position) {

        MainData data  dataArrayList.get(position);

        holder.textView.setText(data.getArabic());
        holder.textView1.setText(data.getEnglish());
        holder.textView2.setText(data.getTranslation());

    }

    @Override
    public int getItemCount() {
        return dataArrayList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        TextView textView;
        TextView textView1;
        TextView textView2;


        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            textView  itemView.findViewById(R.id.ar);
            textView1  itemView.findViewById(R.id.eng);
            textView2  itemView.findViewById(R.id.trn);

        }
    }
}

MainData class

public class MainData {

    public MainData(String arabic, String english, String translation) {
        this.arabic  arabic;
        this.english  english;
        this.translation  translation;
    }

    private String arabic;

    private String english;

    private String translation;

    public String getArabic(){
        return arabic;
    }
    public void setArabic(String arabic){
        this.arabic  arabic;
    }

    public String getEnglish(){
        return english;
    }
    public void setEnglish(String english){
        this.english  english;
    }

    public String getTranslation(){
        return translation;
    }
    public void setTranslation(String translation){
        this.translation  translation;
    }

}

I dont know what is wrong in my whether it is in test(activity), or adapter, or Maindata class. Please help, Thank you in advance.

Solution

The issue you are seeing originates from the fact that you are first creating an Adapter to your recycler view without initializing ArrayList<MainData> dataArrayList.

You are making a network request, which takes time, and once you create an adapter to your recycler view, in the background, it is trying to set data to itself using what you provided.

If you initialize your dataArrayList to be an empty array list, the exception you are seeing will disappear.

public class test extends AppCompatActivity {

RecyclerView recyclerView;
ArrayList<MainData> dataArrayList  new ArrayList<>(); // <----
MainAdapter adapter;
RequestQueue requestQueue;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test);

    recyclerView  findViewById(R.id.recycler_view);

    adapter  new MainAdapter(dataArrayList,test.this);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setAdapter(adapter);
    dataArrayList  new ArrayList<>();
    requestQueue  Volley.newRequestQueue(this);

    parseJson();
}

You could also opt to create and set your adapter only after your parse the response from your network request.

Answered By – tomerpacific

Leave a Comment