You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Retrofit2关联NullPointerException问题求助(Pokedex应用开发)

问题诊断与解决方案

核心问题是你在Retrofit回调返回有效数据前就初始化了PokeAdapter,或回调中未处理空数据场景,导致向要求非空的Adapter构造函数传入了null。之前未使用RecyclerView时仅打印数据,空数据只会输出null不会触发异常;但Adapter构造参数的非空约束(如val pokes: List<Pokemon>)会直接抛出NullPointerException。

步骤1:修正Adapter的非空兼容

如果需要提前初始化Adapter(避免RecyclerView空状态),可以让Adapter默认接受空列表:

// PokeAdapter.kt
class PokeAdapter(val pokes: List<Pokemon> = emptyList()) : RecyclerView.Adapter<PokeAdapter.ViewHolder>() {
    // 你的ViewHolder与数据绑定逻辑
}

步骤2:调整MainActivity的数据加载逻辑

确保仅在Retrofit返回有效数据后更新Adapter,同时处理响应体为空的异常情况:

// MainActivity.kt
private lateinit var recyclerView: RecyclerView

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    recyclerView = findViewById(R.id.recyclerView)
    recyclerView.layoutManager = LinearLayoutManager(this)
    
    // 先初始化空列表的Adapter
    val adapter = PokeAdapter()
    recyclerView.adapter = adapter

    // 初始化Retrofit并发起请求
    val retrofit = Retrofit.Builder()
        .baseUrl("https://pokeapi.co/api/v2/")
        .addConverterFactory(GsonConverterFactory.create())
        .build()

    val apiService = retrofit.create(ApiService::class.java)
    apiService.getPokemons().enqueue(object : Callback<PokemonResponse> {
        override fun onResponse(call: Call<PokemonResponse>, response: Response<PokemonResponse>) {
            // 先检查响应体与数据列表是否非空
            response.body()?.results?.let { pokemonList ->
                // 更新Adapter数据
                val newAdapter = PokeAdapter(pokemonList)
                recyclerView.adapter = newAdapter
                // 推荐方式:给Adapter添加setData方法,避免重复创建实例
                // adapter.setData(pokemonList)
                // adapter.notifyDataSetChanged()
            } ?: run {
                Log.e("MainActivity", "响应体为空,未获取到宝可梦数据")
            }
        }

        override fun onFailure(call: Call<PokemonResponse>, t: Throwable) {
            Log.e("MainActivity", "数据请求失败", t)
        }
    })
}

步骤3:验证数据类与ApiService的正确性

确保数据类结构完全匹配Pokemon API的返回格式:

// PokemonResponse.kt
data class PokemonResponse(
    val results: List<Pokemon>
)

data class Pokemon(
    val name: String,
    val url: String
)

ApiService接口定义需准确:

// ApiService.kt
interface ApiService {
    @GET("pokemon")
    fun getPokemons(): Call<PokemonResponse>
}

步骤4:检查依赖配置

确认build.gradle(Module级别)已正确引入所需依赖:

dependencies {
    // Retrofit核心与Gson解析
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
    // RecyclerView
    implementation 'androidx.recyclerview:recyclerview:1.3.2'
}

额外优化建议

  • 给Adapter添加setData方法,避免每次更新数据都重新创建Adapter实例:
// PokeAdapter.kt
fun setData(newPokes: List<Pokemon>) {
    // 若pokes为可变列表,直接替换数据;否则调整为var类型重新赋值
    (pokes as? MutableList)?.apply {
        clear()
        addAll(newPokes)
    } ?: run {
        // 若pokes是不可变List,需将其改为var后重新赋值
    }
    notifyDataSetChanged()
}
  • 添加加载状态布局,在请求未完成时显示加载提示,提升用户体验。

内容的提问来源于stack exchange,提问作者Soham Chougule

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 11:36:00