Android Java中如何合并接口回调返回的两个Adapter及空指针问题解决
问题根源
- Retrofit的
enqueue是异步网络请求,调用后会立刻返回,不会等待接口响应完成再执行后续代码。你调用完两个数据拉取方法后立刻初始化ConcatAdapter时,两个接口的onResponse回调还没有触发,adKecamatan、adKabupaten两个变量还处于未赋值的空状态,所以会出现空值崩溃。
解决方法
你需要等待两个接口都请求完成、两个Adapter都初始化完成后,再创建ConcatAdapter绑定到RecyclerView,可通过请求计数器实现,修改代码参考如下:
- 先在Activity中添加成员变量记录请求完成数:
// 记录已完成的请求数量 private int requestFinishedCount = 0;
- 修改两个请求的回调逻辑,每个请求完成后调用公共校验方法:
private void fetchDataKabupaten(){ progressBar.setVisibility(View.VISIBLE); token = getIntent().getStringExtra("token"); Call<KabupatenModel> kabupatenModelCall = RetrofitClient.getLoginInterface().getKabupatenData("Bearer "+token); kabupatenModelCall.enqueue(new Callback<KabupatenModel>() { @Override public void onResponse(Call<KabupatenModel> call, Response<KabupatenModel> response) { kabupatenList = response.body().getKabupaten(); adKabupaten = new KabupatenAdapter(MainActivity.this, kabupatenList); checkAndSetConcatAdapter(); progressBar.setVisibility(View.GONE); } @Override public void onFailure(Call<KabupatenModel> call, Throwable t) { progressBar.setVisibility(View.GONE); // 可自行添加请求失败的提示逻辑 checkAndSetConcatAdapter(); } }); } private void fetchDataKecamatan(){ progressBar.setVisibility(View.VISIBLE); token = getIntent().getStringExtra("token"); Call<KecamatanModel> kecamatanModelCall = RetrofitClient.getLoginInterface().getKecamatanData("Bearer " + token); kecamatanModelCall.enqueue(new Callback<KecamatanModel>() { @Override public void onResponse(Call<KecamatanModel> call, Response<KecamatanModel> response) { kecamatanList = response.body().getKecamatan(); adKecamatan = new KecamatanAdapter(MainActivity.this, kecamatanList); checkAndSetConcatAdapter(); progressBar.setVisibility(View.GONE); } @Override public void onFailure(Call<KecamatanModel> call, Throwable t) { progressBar.setVisibility(View.GONE); // 可自行添加请求失败的提示逻辑 checkAndSetConcatAdapter(); } }); }
- 新增校验方法,判断两个请求是否都完成:
private void checkAndSetConcatAdapter() { requestFinishedCount++; // 两个请求都完成后再初始化ConcatAdapter if (requestFinishedCount == 2) { if (adKecamatan != null && adKabupaten != null) { concatAdapter = new ConcatAdapter(adKecamatan, adKabupaten); rV.setAdapter(concatAdapter); } // 重置计数,方便后续刷新数据时复用 requestFinishedCount = 0; } }
- 原有调用逻辑只保留请求触发代码即可:
fetchDataKabupaten(); fetchDataKecamatan();
额外注意事项
- 如果允许单个接口请求失败时,仍展示另一个接口的正常数据,可自行调整校验逻辑,不需要强制等待两个请求都成功再设置Adapter。
- 如果有下拉刷新等需要重新拉取数据的场景,刷新前要重置
requestFinishedCount的值,避免计数错误。
内容的提问来源于stack exchange,提问作者galaxyan12
相关产品推荐
相关产品推荐

