Retrofit请求失败与RecyclerView未绑定适配器问题求助
问题排查与修复方案
我来帮你解决这两个问题,咱们逐个分析:
1. Retrofit请求失败(onResponse未触发)
这是核心问题,直接导致后续RecyclerView无法正常加载。你的API返回的是单个DataResponse对象(而非列表),但你的ApiInterface错误地定义了返回Call<List<DataResponse>>,这会让Gson解析时直接失败,触发onFailure回调。
修复步骤:
首先修改ApiInterface的方法定义,返回单个DataResponse的Call:
public interface ApiInterface { @GET("users") Call<DataResponse> getUsers(@Query("page") int page, @Query("per_page") int per_page); }
然后调整MainActivity里的请求代码,适配返回类型:
Call<DataResponse> call = apiInterface.getUsers(page_num, per_page); call.enqueue(new Callback<DataResponse>() { @Override public void onResponse(Call<DataResponse> call, Response<DataResponse> response) { if (response.isSuccessful() && response.body() != null) { Toast.makeText(MainActivity.this, "Response success....", Toast.LENGTH_SHORT).show(); List<Data> data = response.body().getData(); // 更新adapter数据并通知刷新 adapter.addData(data); adapter.notifyDataSetChanged(); Toast.makeText(MainActivity.this, "First page is loaded...", Toast.LENGTH_SHORT).show(); progressBar.setVisibility(View.GONE); } } @Override public void onFailure(Call<DataResponse> call, Throwable t) { Toast.makeText(MainActivity.this, "请求失败:" + t.getMessage(), Toast.LENGTH_SHORT).show(); progressBar.setVisibility(View.GONE); } });
另外,注意Data类的访问权限:原代码中Data是默认包访问权限,如果MainActivity不在同一个包下,会无法访问它的字段。建议把Data改成public static class Data:
public class DataResponse { @SerializedName("page") private int page; @SerializedName("per_page") private int per_page; @SerializedName("total") private int total; @SerializedName("total_pages") private int total_pages; @SerializedName("data") List<Data> data; // ... 原有getter方法 ... public static class Data { @SerializedName("id") private int id; @SerializedName("first_name") private String first_name; @SerializedName("last_name") private String last_name; @SerializedName("avatar") private String avatar; // ... 原有getter方法 ... } }
2. RecyclerView "No adapter attached; skipping layout" 错误
这个错误是因为Retrofit请求是异步的,在请求完成前,RecyclerView没有绑定任何adapter,系统会跳过布局绘制。
修复步骤:
在onCreate中先初始化一个空的adapter并绑定到RecyclerView,后续请求成功后再更新数据:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recyclerView = findViewById(R.id.recyclerView); layoutManager = new GridLayoutManager(this, 2); recyclerView.setHasFixedSize(true); recyclerView.setLayoutManager(layoutManager); // 先初始化空的adapter并设置给RecyclerView adapter = new RecyclerAdapter(new ArrayList<>(), MainActivity.this); recyclerView.setAdapter(adapter); apiInterface = ApiClient.getApiClient().create(ApiInterface.class); progressBar = findViewById(R.id.progressBar); progressBar.setVisibility(View.VISIBLE); // ... 发起Retrofit请求的代码 ... }
同时优化RecyclerAdapter的addData方法,确保数据更新逻辑更合理:
public void addData(List<Data> data){ dataList.addAll(data); // 如果需要刷新全部数据,可以改成: // dataList.clear(); // dataList.addAll(data); }
最后验证点
- 确保你已经添加了Retrofit、Gson、RecyclerView、Glide的依赖到build.gradle中
- 检查网络权限是否在AndroidManifest.xml中声明:
<uses-permission android:name="android.permission.INTERNET" />
内容的提问来源于stack exchange,提问作者Taufiq Rahman
相关产品推荐
相关产品推荐

