在RecyclerView中展示OkHttp+Gson获取的GET数据时出现类型转换异常
解决OkHttp+Gson解析后RecyclerView展示的Class Cast Exception问题
我来帮你排查这个类型转换异常的问题,这类问题大多出在数据解析的类型匹配或者RecyclerView Adapter的泛型适配上,咱们一步步拆解解决:
1. 先揪出最可能的根源:Gson解析后的数组转List错误
从你的代码片段看,你定义了Hero[] heroes和List<Hero> heroList,很多人会在这里踩坑——直接把数组强转成List,比如写heroList = (List<Hero>) Arrays.asList(heroes);,这其实是错误的!
正确的做法有两种:
- 把数组转成可修改的ArrayList:
// 先解析成Hero数组 heroes = new Gson().fromJson(response.body().string(), Hero[].class); // 再转成ArrayList,避免强转问题 heroList = new ArrayList<>(Arrays.asList(heroes)); - 或者直接让Gson解析成List类型:
// 借助TypeToken获取List<Hero>的类型 Type heroListType = new TypeToken<List<Hero>>(){}.getType(); // 直接解析为List<Hero> heroList = new Gson().fromJson(response.body().string(), heroListType);
2. 检查RecyclerAdapter的泛型是否匹配
你的Adapter必须是针对Hero类型的,不能混用String类型的列表(比如你代码里的demo)。举个正确的Adapter定义示例:
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> { // 泛型必须是List<Hero>,不能是List<String> private List<Hero> heroList; // 构造方法接收List<Hero> public RecyclerAdapter(List<Hero> heroList) { this.heroList = heroList; } @Override public void onBindViewHolder(ViewHolder holder, int position) { // 这里获取的是Hero对象,不是String! Hero currentHero = heroList.get(position); // 绑定Hero的属性到UI,比如名字、图片 holder.heroNameTv.setText(currentHero.getName()); // ...其他UI绑定逻辑 } // ViewHolder和其他方法省略... }
3. 初始化Adapter时别传错列表
你代码里有个List<String> demo,一定要确保初始化Adapter时传入的是heroList,而不是不小心传成了demo:
// 解析完成后,在UI线程更新RecyclerView runOnUiThread(() -> { adapter = new RecyclerAdapter(heroList); // 这里必须传heroList recyclerView.setAdapter(adapter); // 别忘了设置LayoutManager,否则RecyclerView不会显示 recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this)); });
4. 最后检查子线程更新UI的问题
OkHttp的回调是在子线程执行的,所以更新RecyclerView必须切换到UI线程,用runOnUiThread包裹,否则不仅可能报错,数据也不会显示。
给你贴一段完整的OkHttp请求+解析+Adapter初始化的正确代码片段参考:
client = new OkHttpClient(); progressDialog = new ProgressDialog(this); progressDialog.setMessage("Loading..."); progressDialog.show(); Request request = new Request.Builder().url(URL).build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { progressDialog.dismiss(); runOnUiThread(() -> Toast.makeText(MainActivity.this, "请求失败,请重试", Toast.LENGTH_SHORT).show()); } @Override public void onResponse(Call call, Response response) throws IOException { progressDialog.dismiss(); if (response.isSuccessful()) { String jsonResponse = response.body().string(); // 直接解析为List<Hero> Type listType = new TypeToken<List<Hero>>(){}.getType(); heroList = new Gson().fromJson(jsonResponse, listType); // 切换到UI线程更新RecyclerView runOnUiThread(() -> { adapter = new RecyclerAdapter(heroList); recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this)); recyclerView.setAdapter(adapter); }); } } });
按照这几步排查,应该就能解决你的Class Cast Exception问题啦!
内容的提问来源于stack exchange,提问作者Pawan Lakhotia
相关产品推荐
相关产品推荐

