如何解决与retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall相关的NullPointerException

问题描述 投票:0回答:1

我正在尝试制作一个 Pokedex 应用程序,使用 Retrofit2 从 API 获取神奇宝贝数据。 当我尝试运行它时,它记录以下错误 错误:

FATAL EXCEPTION: main
                                                                                                    Process: com.example.pokemonapp, PID: 10766
                                                                                                    java.lang.NullPointerException: Parameter specified as non-null is null: method com.example.pokemonapp.PokeAdapter.<init>, parameter pokes
                                                                                                        at com.example.pokemonapp.PokeAdapter.<init>(Unknown Source:7)
                                                                                                        at com.example.pokemonapp.MainActivity$getPokemon$1.onResponse(MainActivity.kt:31)
                                                                                                        at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1.lambda$onResponse$0$retrofit2-DefaultCallAdapterFactory$ExecutorCallbackCall$1(DefaultCallAdapterFactory.java:89)
                                                                                                        at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1$$ExternalSyntheticLambda0.run(Unknown Source:6)
                                                                                                        at android.os.Handler.handleCallback(Handler.java:958)
                                                                                                        at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                                                        at android.os.Looper.loopOnce(Looper.java:205)
                                                                                                        at android.os.Looper.loop(Looper.java:294)
                                                                                                        at android.app.ActivityThread.main(ActivityThread.java:8177)
                                                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                                                        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
                                                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)

MainActivity.kt

class MainActivity : AppCompatActivity() {
    lateinit var adapter: PokeAdapter
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        getPokemon()
    }

    private fun getPokemon() {
            val pokeball: Call<PokeApiResponse> = PokeInterface.ApiService.pokeInstance.getPokemonList()
            pokeball.enqueue(object: Callback<PokeApiResponse> {
                override fun onResponse(
                    call: Call<PokeApiResponse>,
                    response: Response<PokeApiResponse>
                ) {
                    val pokedex = response.body()
                    if(pokedex!= null)
                    {
                        Log.d("CHECK", pokeball.toString())
                        adapter = PokeAdapter(this@MainActivity, pokedex.pokemons)
                        val pokeList = findViewById<RecyclerView>(R.id.pokemonList)
                        pokeList.adapter = adapter
                        pokeList.layoutManager = LinearLayoutManager(this@MainActivity)
                    }
                }


                override fun onFailure(call: Call<PokeApiResponse>, t: Throwable) {
                    Log.d("CHECK", "Error in fetching Pokemon", t)
                }
            })
        }
    }

ApiService.kt

const val BASE_URL = "https://raw.githubusercontent.com/Biuni/PokemonGO-Pokedex/master/"

interface PokeInterface{
    @GET("pokedex.json")
    fun getPokemonList() : Call<PokeApiResponse>

    //https://raw.githubusercontent.com/Biuni/PokemonGO-Pokedex/master/pokedex.json

    object ApiService{
        val pokeInstance: PokeInterface
        init{
            val retrofit = Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build()
            pokeInstance = retrofit.create(PokeInterface::class.java)
        }
    }
}

PokeApiResponse.kt

data class PokeApiResponse(
    val pokemons: List<Poke>
)

戳.kt

data class Poke(
    val name: String,
    val img: String
)

PokeAdapter.kt

class PokeAdapter(val context: Context, val pokes: List<Poke>): RecyclerView.Adapter<PokeAdapter.PokemonViewHolder>() {


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PokemonViewHolder {
        val view = LayoutInflater.from(context).inflate(R.layout.item_layout, parent, false)
        return PokemonViewHolder(view)
    }

    override fun getItemCount(): Int {
        return pokes.size
    }

    override fun onBindViewHolder(holder: PokemonViewHolder, position: Int) {
        val pokemon = pokes[position]
        holder.pokeTitle.text = pokemon.name
    }

    class PokemonViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var pokeImage = itemView.findViewById<ImageView>(R.id.pokeImage)
        var pokeTitle = itemView.findViewById<TextView>(R.id.pokeName)
    }
}

build.gradle

implementation ("com.squareup.retrofit2:retrofit:2.9.0")
implementation ("com.squareup.retrofit2:converter-gson:2.9.0")

在 MainActivity.kt 中,我尝试记录使用标签“CHECK”获取的数据,它记录以下消息:retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall@6d104a9

早些时候,当我没有实现 RecyclerView 时,retrofit 可以正确获取数据,并且获取的数据也正确记录在“CHECK”标签下,但是现在它不断给出 DefaultCallAdapterFactory$ExecutorCallbackCall 消息。

我花了几个小时试图在网上寻找解决方案,但没有任何效果。 任何在这方面的帮助将不胜感激。

android api rest kotlin retrofit2
1个回答
0
投票

我认为 NPE 可能来自您的日志

override fun onResponse(call: Call<PokeApiResponse>, response: Response<PokeApiResponse>) {
    val pokedex = response.body()
    if (pokedex != null) {
        Log.d("CHECK", "Received ${pokedex.pokemons.size} Pokemon")
        adapter = PokeAdapter(this@MainActivity, pokedex.pokemons)
        val pokeList = findViewById<RecyclerView>(R.id.pokemonList)
        pokeList.adapter = adapter
        pokeList.layoutManager = LinearLayoutManager(this@MainActivity)
    }
}

尝试记录 pokedex 列表而不是 pokeball

© www.soinside.com 2019 - 2024. All rights reserved.