java - 使用 Retrofit 响应中的空指针异常

标签 java android retrofit2

我再次尝试使用 TMBD api。我正在使用 recyclerview 将数据映射到列表中。但是我从改造响应中得到的响应为空。

主要 Activity :

public class MainActivity extends AppCompatActivity {

    public final static String BASE_URL="https://api.themoviedb.org";
    public final static String apiKey="<ApiKey>";
    public final static String language="en-US";
    public final static String TAG="tag";

    @BindView(R.id.recyclerView)
    RecyclerView movieList;

    DisplayAdapter adapter;
    MovieResponse result;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ButterKnife.bind(this);

        Retrofit retrofit=new Retrofit.Builder()
                                .baseUrl(BASE_URL)
                                .addConverterFactory(GsonConverterFactory.create())
                                .build();

        ApiInterface apiInterface=retrofit.create(ApiInterface.class);

        apiInterface.getMovies(apiKey,language,1)
                .enqueue(new Callback<MovieResponse>() {
                    @Override
                    public void onResponse(Call<MovieResponse> call, Response<MovieResponse> response) {
                        if(response.isSuccessful())
                        {
                            result=response.body();
                            Log.e(TAG, "onCreate: "+result );
                        }
                    }

                    @Override
                    public void onFailure(Call<MovieResponse> call, Throwable t) { }
                });

        Log.e(TAG, "onCreate: "+result );
        adapter=new DisplayAdapter(getApplicationContext(),result);
        RecyclerView.LayoutManager layoutManager=new GridLayoutManager(getApplicationContext(),1);
        movieList.setLayoutManager(layoutManager);
        movieList.setAdapter(adapter);
    }
}

响应类:

public class MovieResponse {

    private int page;
    private int total_results;
    private int total_pages;
    private List<ResultsBean> results;

    public int getPage() {
        return page;
    }

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

    public int getTotal_results() {
        return total_results;
    }

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

    public int getTotal_pages() {
        return total_pages;
    }

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

    public List<ResultsBean> getResults() {
        return results;
    }

    public void setResults(List<ResultsBean> results) {
        this.results = results;
    }

    public static class ResultsBean {

        private double popularity;
        private int vote_count;
        private boolean video;
        private String poster_path;
        private int id;
        private boolean adult;
        private String backdrop_path;
        private String original_language;
        private String original_title;
        private String title;
        private double vote_average;
        private String overview;
        private String release_date;
        private List<Integer> genre_ids;

        public double getPopularity() {
            return popularity;
        }

        public void setPopularity(double popularity) {
            this.popularity = popularity;
        }

        public int getVote_count() {
            return vote_count;
        }

        public void setVote_count(int vote_count) {
            this.vote_count = vote_count;
        }

        public boolean isVideo() {
            return video;
        }

        public void setVideo(boolean video) {
            this.video = video;
        }

        public String getPoster_path() {
            return poster_path;
        }

        public void setPoster_path(String poster_path) {
            this.poster_path = poster_path;
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public boolean isAdult() {
            return adult;
        }

        public void setAdult(boolean adult) {
            this.adult = adult;
        }

        public String getBackdrop_path() {
            return backdrop_path;
        }

        public void setBackdrop_path(String backdrop_path) {
            this.backdrop_path = backdrop_path;
        }

        public String getOriginal_language() {
            return original_language;
        }

        public void setOriginal_language(String original_language) {
            this.original_language = original_language;
        }

        public String getOriginal_title() {
            return original_title;
        }

        public void setOriginal_title(String original_title) {
            this.original_title = original_title;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public double getVote_average() {
            return vote_average;
        }

        public void setVote_average(double vote_average) {
            this.vote_average = vote_average;
        }

        public String getOverview() {
            return overview;
        }

        public void setOverview(String overview) {
            this.overview = overview;
        }

        public String getRelease_date() {
            return release_date;
        }

        public void setRelease_date(String release_date) {
            this.release_date = release_date;
        }

        public List<Integer> getGenre_ids() {
            return genre_ids;
        }

        public void setGenre_ids(List<Integer> genre_ids) {
            this.genre_ids = genre_ids;
        }
    }
}

API 接口(interface):

public interface ApiInterface {

    @GET("3/movie/popular")
    Call<MovieResponse> getMovies(
            @Query("api_key") String apiKey,
            @Query("language")String language,
            @Query("page")int page
    );
}

我正在学习 API 调用的概念。我不明白为什么响应为空。如果有人能解释原因,那将非常有帮助。

最佳答案

这可以是您发布的几件事。

可能是 Java 模型与 JSON 不匹配。你必须仔细检查一下。

可能是您遇到了错误,在这种情况下,改造没有 response.body(),而是 response.errorBody() .您可以通过调试和检查 response.erroeBody().string() 来检查这一点。

或者它可能是异步行为像处理同步行为一样处理的经典示例。

adapter=new DisplayAdapter(getApplicationContext(),result);

在这种情况下,您使用的是 result,但它是在改造回调中分配的,该回调很可能在您创建适配器后完成,因此 result 仍然为 null。

您可以移动适配器的创建并将其设置到回调中的列表:

public void onResponse(Call<MovieResponse> call, Response<MovieResponse> response) {
                    if(response.isSuccessful())
                    {
                        result=response.body();
                        Log.e(TAG, "onCreate: "+result );

                       adapter=new DisplayAdapter(getApplicationContext(),result);
                       RecyclerView.LayoutManager layoutManager=new GridLayoutManager(getApplicationContext(),1);
                       movieList.setLayoutManager(layoutManager);
                       movieList.setAdapter(adapter);
                    }
                }

这些是我唯一想到的事情。希望对您有所帮助。


编辑

查看 github 项目后,我发现唯一导致应用程序崩溃的是 DisplayAdapter.java 第 44 行:

holder.movieRating.setText((int) listOfMovies.getResults().get(position).getVote_average());

当您调用接受 intsetText 时,您实际上是在调用一个方法,该方法将在您的 strings.xml 中查找字符串id 等于您传入的 int。在这种情况下,您将投票平均值作为 int 传递。我猜你想要的是显示投票平均值,所以解决方案是将 double 投票平均值转换为字符串。这可以通过 String.valueOf 轻松实现:

holder.movieRating.setText(String.valueOf(listOfMovies.getResults().get(position).getVote_average()));

也许最有趣的一点是日志消息 android.content.res.Resources$NotFoundException: String resource ID #0x7。尝试查找不存在的字符串时抛出此错误。

关于java - 使用 Retrofit 响应中的空指针异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58786049/

相关文章:

java - JSF 1.2 : Options for dropdown list not updated when it is set for the first time

android - Kotlin 数据类 |添加我自己的变量而不是 JSON 键

java - OkHttpClient 在将 Retrofit 更新为 Retrofit 2 后损坏

java - 由于无法加载主类错误,无法运行 JAR 文件

java - 在水平 LinearLayout 上膨胀多个 TextView

Java Properties 属性值 - 带有前导空格的消息

java - 如何在没有 XML 的情况下在 AlertDialog Builder 中显示进度条以及其他元素?

android - Game Maker Export 问题

java - CI 中的 Android 配置值

java - 如何在请求中传递参数?