首页 > 解决方案 > 为什么在获取 JSON 时会出现 NullPointerException?

问题描述

我不断收到 NullPointerException return place
当我调试应用程序时,代码会跳过onFailure()andonResponse()方法。

以前,这可行,但我将其重构为当前类。

class Repository private constructor() {

    private val baseUrl: String = "http://api.openweathermap.org/"

    val client = OkHttpClient.Builder()
            .addInterceptor(HttpLoggingInterceptor()
            .setLevel(HttpLoggingInterceptor.Level.BODY))
            .build()

    val retrofit = Retrofit.Builder()
            .baseUrl(baseUrl)
            .addConverterFactory(MoshiConverterFactory.create())
            .client(client)
            .build()

    val networkApi = retrofit.create(NetworkApi::class.java)


    private object Holder { val INSTANCE = Repository() }

    companion object {

        val instance: Repository by lazy { Holder.INSTANCE }

    }

    fun fetchWeatherData(placeName: String): Place {

        var place: Place? = null

        val call: Call<Place> = networkApi.getPlaceWeather(placeName)

        call.enqueue(object : Callback<Place> {

            override fun onFailure(call: Call<Place>?, t: Throwable?) {
                println(t?.message)
            }

            override fun onResponse(call: Call<Place>?, response: Response<Place>?) {

                if (response != null && response.isSuccessful && response.body() != null) {

                    place = response.body() as Place

                    println(place.toString())
                }
            }
        })

        return place!!
    }
}


class MainPresenter(private val view: MainContract.View, val context: Context) : MainContract.Presenter {

    val repository = Repository.instance

    ...

    override fun updateListOfPlaces() {

        var places = mutableListOf<Place>()

        for (index in 0 until favPlaceStrings.size) {
            places.add(repository.fetchWeatherData(favPlaceStrings.elementAt(index)))
        }

        view.showFavouritePlaces(places)
    }

}

标签: kotlinretrofitretrofit2

解决方案


您使用改造的方式使其具有异步行为,这意味着其中的代码onFailure可能onResponse会在您有机会从fetchWeatherData. 换句话说,你不能假设place当你返回时它会有一个值fetchWeatherData,这实际上是正在发生的事情,place仍然是null并且调用!!将导致你遇到的空指针异常。

要解决此问题,您可以将使用改造的方式更改为同步,或者使用回调之类的方法。

就个人而言,我更喜欢回调方法/反应流,你可以在这里查看

使代码同步很可能会导致其他问题,例如主线程上的网络调用,这是不允许的并导致应用程序崩溃。


推荐阅读