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
相关产品推荐
相关产品推荐

