java - 如何使用Java中的Volley库将JSON api数据放入recyclerview?

Posted

技术标签:

【中文标题】java - 如何使用Java中的Volley库将JSON api数据放入recyclerview?【英文标题】:How to put JSON api data to recyclerview using Volley library in java? 【发布时间】:2021-10-28 04:22:20 【问题描述】:

我正在尝试使用 volley 库将 JSON api 数据放入 recyclerview。 我的api url=here

但它给出了这个错误,我的 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)

我的活动(测试)

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();

    

我的适配器(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 类

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;
    


我不知道我的问题是在测试(活动)、适配器还是 Maindata 类中。 请帮忙,提前谢谢。

【问题讨论】:

【参考方案1】:

您看到的问题源于您首先为您的回收站视图创建了一个适配器,而没有初始化ArrayList&lt;MainData&gt; dataArrayList

您正在发出网络请求,这需要时间,并且一旦您为回收站视图创建了适配器,它就会在后台尝试使用您提供的内容为自己设置数据。

如果您将 dataArrayList 初始化为一个空数组列表,您看到的异常将会消失。

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();

您也可以选择仅在解析网络请求的响应后创建和设置适配器。

【讨论】:

异常现在消失了,但是没有返回数据! 那么你的网络请求的响应没有返回任何数据。我建议调试响应并查看您收到的内容。无论如何,如果我的回答有帮助,请标记它。

以上是关于java - 如何使用Java中的Volley库将JSON api数据放入recyclerview?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用简单的 JSON 库将 json 文件读入 java

如何在 android java 中使用 volley 获取内部信息对象

如何使用 Java 库将标记的 YAML 对象转换为 JSON 对象?

使用 jackson-dataformat-xml 库将 XML 中的空标签转换为 java 属性

如何使用处理 Java 库将自定义形状数组和字符串数组合并到 JSON 对象中

在 Android volley 库中使用 cookie