【问题标题】:OMDb Api doesn't show any result - Kotlin, Android StudioOMDb Api 没有显示任何结果 - Kotlin,Android Studio
【发布时间】:2021-12-29 16:22:18
【问题描述】:

我一步一步仔细地跟踪了一切,但我找不到问题所在。 每当我填写要搜索的电影的名称时,应用程序就会崩溃,并显示如下: 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)
    }


}

【问题讨论】:

    标签: android kotlin omdbapi


    【解决方案1】:

    我认为您收到了错误响应,这就是为什么 response.body()null。您应该优雅地处理错误响应,而不是期望正文始终不为空,但这是另一回事。

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

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

    “标题”应该是@Query 参数而不是@Path 参数,因为API url 中的&amp;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);
    

    【讨论】:

    • 我试过你说的,但没用。现在我收到这条消息:java.lang.IllegalArgumentException: Missing either GET URL or Url parameter.
    • 对,尝试在@GET("") 中使用空字符串。如果这不起作用,我们将不得不清理 baseUrl 并将 apiKey 移动到方法调用中(或者更好地移动到拦截器中,以便所有调用都具有 apiKey)。
    • @Get("") 方法不起作用。我将 api 密钥添加到 @Get 方法并且它起作用了。谢谢。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2017-03-13
      • 2015-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多