I am trying to put JSON api data to recyclerview using volley library. My Api url=here
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.
Advertisement
Answer
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.