【问题标题】:TMDB api trending endpoint call returns a null objectTMDB api 趋势端点调用返回空对象
【发布时间】:2020-01-03 09:42:39
【问题描述】:

我正在使用改造对 android 中的 themoviedb.org api 进行 api 调用。我期望响应中有一个包含电影列表的 json 数组,但是当我调用我的 POJO 类的 getResults 方法时,我得到一个空对象引用。请协助。

这是我收到的错误消息;

2020-01-03 12:28:10.396 20851-20851/com.popularmovies E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.popularmovies, PID: 20851
    java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.gson.JsonArray com.popularmovies.TrendingPojo.getResults()' on a null object reference
        at com.popularmovies.TrendingFragment$1.onResponse(TrendingFragment.java:109)
        at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:71)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7045)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)

这是我的api接口

import retrofit2.Call;

import retrofit2.http.GET;
import retrofit2.http.Path;
import retrofit2.http.Query;

public interface TmdbApi {
    final String BASE_URL = "https://api.themoviedb.org/4/";

    @GET("list/{id}")
    Call<CategoryJsonResponse> getMovies(@Path ("id") String id, @Query("api_key") String api_key);

    @GET("discover/movie")
    Call<DiscoverPOJO> getDiscover(@Query("sort_by") String sort_by,@Query("api_key") String api_key);

    @GET("trending/{media_type}/{time_window}")
    Call<TrendingPojo> getTrending(@Path("media_type") String media_type, @Path("time_window") String time_window, @Query("api_key") String api_key);
}

我的问题在于趋势端点。

下面是我的 POJO 类

package com.popularmovies;

import com.google.gson.JsonArray;


public class TrendingPojo {
    private int page;
    private JsonArray results;
    private int total_results;
    private int total_pages;



    //Default constructor for api calls
    public TrendingPojo(int page, JsonArray results, int total_pages, int total_results) {
        this.page = page;
        this.results = results;
        this.total_results = total_results;
        this.total_pages = total_pages;
    }


    public int getPage() {
        return page;
    }

    public JsonArray getResults() {
        return results;
    }

    public int getTotal_results() {
        return total_results;
    }

    public int getTotal_pages() {
        return total_pages;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public void setResults(JsonArray results) {
        this.results = results;
    }

    public void setTotal_results(int total_results) {
        this.total_results = total_results;
    }

    public void setTotal_pages(int total_pages) {
        this.total_pages = total_pages;
    }

}

以下是我使用改造进行 api 调用的片段;

package com.popularmovies;


import android.os.Bundle;

import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.util.Collection;
import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

import static com.popularmovies.DiscoverFragment.API_KEY;


public class TrendingFragment extends Fragment implements MovieAdapter.MovieAdapterOnclickHandler {
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;
    private View rootView;
    private ProgressBar progressBar;
    private RecyclerView mRecyclerView;
    private MovieAdapter movieAdapter;
    private List<Movies> moviez;


    public TrendingFragment() {
        // Required empty public constructor
    }
    // TODO: Rename and change types and number of parameters

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.fragment_trending, container, false);
        progressBar = rootView.findViewById(R.id.trending_pb);
        progressBar.setVisibility(View.VISIBLE);
        mRecyclerView = rootView.findViewById(R.id.trending_rv);

        GridLayoutManager layoutManager = new GridLayoutManager(rootView.getContext(), 2);
        mRecyclerView.setLayoutManager(layoutManager);



        mRecyclerView.setHasFixedSize(true);

        movieAdapter = new MovieAdapter(this);

        mRecyclerView.setAdapter(movieAdapter);
        getTrendingResponse();
        return rootView;
    }

    // TODO: Rename method, update argument and hook method into UI event

    private void getTrendingResponse(){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(TmdbApi.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        TmdbApi tmdbApi = retrofit.create(TmdbApi.class);

        Call<TrendingPojo> call = tmdbApi.getTrending("movie","week",API_KEY);
        call.enqueue(new Callback<TrendingPojo>() {
            @Override
            public void onResponse(Call<TrendingPojo> call, Response<TrendingPojo> response) {
                TrendingPojo movies = response.body();
                JsonArray allmovies;
                allmovies =  movies.getResults();
                if(allmovies!= null){
                    for(int i = 0; i < allmovies.size(); i++){
                        Gson gson = new Gson();
                        Type listType = new TypeToken<Collection<Movies>>(){}.getType();
                        moviez =  gson.fromJson(allmovies, listType);
                    }
                    movieAdapter.setData(moviez);
                    progressBar.setVisibility(View.INVISIBLE);
                }

            }

            @Override
            public void onFailure(Call<TrendingPojo> call, Throwable t) {
                Toast.makeText(rootView.getContext(), t.getMessage(), Toast.LENGTH_LONG).show();
            }
        });
    }
    @Override
    public void onDetach() {
        super.onDetach();
    }

    @Override
    public void onClick(int s) {

    }

}

最后,这里是趋势端点的 api 文档的链接。 https://developers.themoviedb.org/3/trending/get-trending

【问题讨论】:

    标签: android retrofit2 themoviedb-api


    【解决方案1】:

    原来问题是我使用的是版本 4 的基本 URL,它为某些端点返回 404 错误代码,而不是版本 3。

    改变

    "https://api.themoviedb.org/4/"
    

    "https://api.themoviedb.org/3/"
    

    是解决方案。

    【讨论】:

      猜你喜欢
      • 2016-03-29
      • 1970-01-01
      • 1970-01-01
      • 2020-05-09
      • 2017-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多