OMDb Api 没有显示任何结果 - Kotlin,Android Studio

OMDb Api doesn't show any result - Kotlin, Android Studio

我一步一步仔细地跟进,但我找不到问题所在。 每当我填写要搜索的电影名称时,应用程序就会崩溃并显示以下内容: java.lang.NullPointerException: response.body() 不能为空

有人知道吗?下面是代码。

MovieList.kt

class MovieList {
    val imdbID: String
    val Title: String
    val Year: String
    val Plot: String
    val Poster: String

    constructor(imdbID: String, Title: String, Year: String, Plot: String, Poster: String) {
        this.imdbID = imdbID
        this.Title = Title
        this.Year = Year
        this.Plot = Plot
        this.Poster = Poster
    }
}

OMDbApi.kt

interface OMDbApi {
    @GET("t={Title}")
    fun getMovieByTitle(@Path("Title") Title: String): Call<MovieList>
}

OMDbApiClient.kt

class OMDbApiClient {

    companion object{
        private var omdbapi: OMDbApi? = null

        fun getOMDbApi(): OMDbApi?{
            if(omdbapi == null){
                omdbapi = Retrofit.Builder()
                    .baseUrl("http://www.omdbapi.com/?&apikey=eb73867f")
                    .addConverterFactory(GsonConverterFactory.create())
                    .build()
                    .create(OMDbApi::class.java);

            }

            return omdbapi
        }

    }

}

FirstFragment.kt

class FirstFragment : Fragment() {
    private lateinit var omdbapiClient: OMDbApi
    private lateinit var tvMovieTitle: TextView
    private lateinit var ivImagePoster: ImageView

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_first, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        omdbapiClient = OMDbApiClient.getOMDbApi()!!

        val movieId: EditText = view.findViewById<EditText>(R.id.TitleId)

        tvMovieTitle = view.findViewById(R.id.MovieTitleId)
        ivImagePoster = view.findViewById(R.id.MoviePosterId)

        movieId.setOnEditorActionListener { v, actionId, event ->
            if(actionId == EditorInfo.IME_ACTION_DONE || actionId == EditorInfo.IME_ACTION_NEXT){
                val movietitle: String = movieId.text.toString()
                searchMovieByTitle(movietitle)
                true
            }
            else{
                Toast.makeText(activity, "Error!", Toast.LENGTH_LONG).show()
                false
            }
        }
    }

    private fun searchMovieByTitle(movietitle: String) {
        omdbapiClient.getMovieByTitle(movietitle).enqueue(object : Callback<MovieList>{
            override fun onResponse(call: Call<MovieList>?, response: Response<MovieList>) {
                displayData(response.body())
                Toast.makeText(activity, "Success!", Toast.LENGTH_LONG).show()
            }

            override fun onFailure(call: Call<MovieList>?, t: Throwable?) {
                Toast.makeText(activity, "Error!", Toast.LENGTH_LONG).show()
            }

        })
    }

    private fun displayData(data: MovieList) {
        tvMovieTitle.text = data.Title
        Glide.with(this).load(data.Poster).into(ivImagePoster)
    }


}

我认为您收到错误响应,这就是 response.body()null 的原因。您应该优雅地处理错误响应,而不是期望主体始终不为空,但这是另一回事。

我认为以下代码行有问题:

interface OMDbApi {
    @GET("t={Title}")
    fun getMovieByTitle(@Path("Title") Title: String): Call<MovieList>
}

'Title' 应该是 @Query 参数而不是 @Path 参数,因为 API url 中的 &t= 部分是查询参数。当它是查询参数时,您也不要将其指定为 @GET.

中路径的一部分

您的代码将变为:

interface OMDbApi {
    @GET("")
    fun getMovieByTitle(@Query("t") title: String): Call<MovieList>
}

做这个改变,看看你是否仍然收到错误响应。您可能需要检查 'Logcat' 选项卡中的日志以查看从 API.

返回的错误

为此,您可能必须启用更高的日志记录级别。这是通过在构建 Retrofit 客户端时添加日志拦截器来完成的。

    // Build a http client with logging enabled
    val client = OkHttpClient.Builder()
        .addInterceptor(HttpLoggingInterceptor().apply {
            // you can also use Level.BODY for even more log information
            level = HttpLoggingInterceptor.Level.BASIC
        })
        .build()
    
    omdbapi = Retrofit.Builder()
        .client(client) // add this line to use your http client
        .baseUrl("http://www.omdbapi.com/?&apikey=eb73867f")
        .addConverterFactory(GsonConverterFactory.create())
        .build()
        .create(OMDbApi::class.java);

下面的代码解决了我的问题。

interface OMDbApi {
    @GET("?apikey=[your api key]&")
    fun getMovieByTitle(@Query("t") Title: String): Call<MovieList>
}