Android中如何等待API响应后向RecyclerView动态加载数据
问题根因排查
从你提供的代码中可定位到最直接的崩溃触发点:
- 你定义的本地占位图数组
EventImages仅包含2个元素,但遍历API返回的JSON数组时,直接用循环下标i取EventImages[i],如果API返回的事件数量超过2,就会触发数组下标越界异常,这是最常见的崩溃原因。 - 次要不规范问题:你将RecyclerView的初始化、LayoutManager设置、Adapter绑定全部放在网络请求的回调中,不符合常规写法,也容易触发空指针或布局加载异常。
修复方案
1. 修复占位图越界问题
如果要复用两张占位图展示不同事件,不要直接用i取数组元素,改成取模运算循环使用占位图:
// 把原有代码 EventImage.addLast(EventImages[i]); 替换为下面的内容 EventImage.addLast(EventImages[i % EventImages.length]);
2. 调整RecyclerView初始化逻辑
把RecyclerView的初始化、LayoutManager设置移到onCreate方法中,网络请求成功后仅更新Adapter数据再通知刷新即可,优化后的onCreate逻辑如下:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_card_list_view_admins); // 提前初始化RecyclerView recyclerView = findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(this)); // 先初始化空数据集和Adapter,后续请求到数据再更新 _id = new LinkedList<>(); EventImage = new LinkedList<>(); Url = new LinkedList<>(); EventTitle = new LinkedList<>(); Clubname = new LinkedList<>(); DateEvent = new LinkedList<>(); adapter = new EventListAdapter(this, EventTitle, EventImage, Clubname, DateEvent); recyclerView.setAdapter(adapter); // 原有请求队列初始化、SharedPreferences设置、网络请求逻辑保留不变 SettingUpRequestQueue(); // ... 其余原有代码不变 }
3. 网络请求成功后更新Adapter数据
把原来回调中重新创建Adapter的逻辑,改成更新原有Adapter的数据集再通知刷新:
@Override public void onResponse(JSONArray response) { // 先清空原有数据 _id.clear(); EventImage.clear(); Url.clear(); EventTitle.clear(); Clubname.clear(); DateEvent.clear(); for(int i = 0; i < response.length(); i++){ try { // 替换为修复后的占位图取法 EventImage.addLast(EventImages[i % EventImages.length]); JSONObject event = response.getJSONObject(i); _id.addLast(event.get("_id").toString()); Url.addLast(event.get("ImageUrl").toString()); EventTitle.addLast(event.get("Title").toString()); Clubname.addLast(event.get("OrganizingClub").toString()); DateEvent.addLast(event.get("Date").toString()); } catch (JSONException e) { e.printStackTrace(); } } // 通知Adapter数据更新即可,不需要重复创建Adapter adapter.notifyDataSetChanged(); }
额外优化建议
你当前代码已经拿到了图片的ImageUrl,后续可以替换本地占位图方案,用Glide、Picasso等图片加载框架加载网络图片,不需要提前准备本地占位图数组,也能从根源避免越界问题。
内容的提问来源于stack exchange,提问作者Venkata Sridhar Sai
相关产品推荐
相关产品推荐

