2017-04-23 13 views
-1

Retrofitライブラリを使用して、現在再生中の映画カテゴリのTMDB APIのJson応答を解析し、結果をRecyclerViewに表示したいとします。私はAPIから取得していますRetrofitライブラリがnullを返すJson Response

Thの生のJSONは、私が作成したモデルクラスはMovie.java

package com.example.vikas.movie.model; 

/** 
* Created by vikas on 22/4/17 
*/ 
import com.google.gson.annotations.SerializedName; 

import java.util.ArrayList; 
import java.util.List; 
public class Movie 
{ 
    @SerializedName("poster_path") 
    private String posterPath; 
    @SerializedName("adult") 
    private boolean adult; 
    @SerializedName("overview") 
    private String overview; 
    @SerializedName("realease_date") 
    private String releaseDate; 
    @SerializedName("genre_ids") 
    private List<Integer> genreIds=new ArrayList<Integer>(); 
    @SerializedName("id") 
    private int id; 
    @SerializedName("original_title") 
    private String originalTitle; 
    @SerializedName("original_language") 
    private String original_language; 
    @SerializedName("title") 
    private String title; 
    @SerializedName("backdrop_path") 
    private String backdrop_path; 
    @SerializedName("popularity") 
    private Double popularity; 
    @SerializedName("vote_count") 
    private int vote_count; 
    @SerializedName("vedeo") 
    private boolean vedeo; 
    @SerializedName("vote_average") 
    private Double vote_average; 


    public Movie(String posterPath, boolean adult, String overview, String releaseDate, List<Integer> genreIds, Integer id, 
       String originalTitle, String original_language, String title, String backdrop_path, Double popularity, 
       Integer vote_count, Boolean vedeo, Double vote_average) { 
     this.posterPath = posterPath; 
     this.adult = adult; 
     this.overview = overview; 
     this.releaseDate = releaseDate; 
     this.genreIds = genreIds; 
     this.id = id; 
     this.originalTitle = originalTitle; 
     this.original_language = original_language; 
     this.title = title; 
     this.backdrop_path = backdrop_path; 
     this.popularity = popularity; 
     this.vote_count = vote_count; 
     this.vedeo = vedeo; 
     this.vote_average = vote_average; 
    } 

    public String getPosterPath() { 
     return posterPath; 
    } 

    public void setPosterPath(String posterPath) { 
     this.posterPath = posterPath; 
    } 

    public boolean isAdult() { 
     return adult; 
    } 

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

    public String getOverview() { 
     return overview; 
    } 

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

    public String getReleaseDate() { 
     return releaseDate; 
    } 

    public void setReleaseDate(String releaseDate) { 
     this.releaseDate = releaseDate; 
    } 

    public List<Integer> getGenreIds() { 
     return genreIds; 
    } 

    public void setGenreIds(List<Integer> genreIds) { 
     this.genreIds = genreIds; 
    } 

    public Integer getId() { 
     return id; 
    } 

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

    public String getOriginalTitle() { 
     return originalTitle; 
    } 

    public void setOriginalTitle(String originalTitle) { 
     this.originalTitle = originalTitle; 
    } 

    public String getOriginalLanguage() { 
     return original_language; 
    } 

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

    public String getTitle() { 
     return title; 
    } 

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

    public String getBackdropPath() { 
     return backdrop_path; 
    } 

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

    public Double getPopularity() { 
     return popularity; 
    } 

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

    public Integer getvote_count() { 
     return vote_count; 
    } 

    public void setVoteCount(Integer voteCount) { 
     this.vote_count = voteCount; 
    } 

    public Boolean getVedeo() { 
     return vedeo; 
    } 

    public void setVedeo(Boolean vedeo) { 
     this.vedeo = vedeo; 
    } 

    public Double getvote_average() { 
     return vote_average; 
    } 

    public void setVoteAverage(Double vote_average) { 
     this.vote_average = vote_average; 
    } 
} 

MovieResponse.java

package com.example.vikas.movie.model; 

/** 
* Created by vikas on 22/4/17. 
*/ 
import com.google.gson.annotations.SerializedName; 
import java.util.List; 
public class MoviesResponse 
{ 
    @SerializedName("page") 
    private int page; 
    @SerializedName("results") 
    private List<Movie>results; 
    @SerializedName("total_results") 
    private int totalResults; 
    @SerializedName("total_pages") 
    private int totalPages; 
    public int getPage() { 
     return page; 
    } 

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

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

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

    public int getTotalResults() { 
     return totalResults; 
    } 

    public void setTotalResults(int totalResults) { 
     this.totalResults = totalResults; 
    } 

    public int getTotalPages() { 
     return totalPages; 
    } 

    public void setTotalPages(int totalPages) { 
     this.totalPages = totalPages; 
    } 




} 

ある

{ 
    "page": 1, 
    "results": [ 
    { 
     "poster_path": "\/tWqifoYuwLETmmasnGHO7xBjEtt.jpg", 
     "adult": false, 
     "overview": "A live-action adaptation of Disney's version of the classic 'Beauty and the Beast' tale of a cursed prince and a beautiful young woman who helps him break the spell.", 
     "release_date": "2017-03-16", 
     "genre_ids": [ 
     14, 
     10749 
     ], 
     "id": 321612, 
     "original_title": "Beauty and the Beast", 
     "original_language": "en", 
     "title": "Beauty and the Beast", 
     "backdrop_path": "\/6aUWe0GSl69wMTSWWexsorMIvwU.jpg", 
     "popularity": 147.254531, 
     "vote_count": 1938, 
     "video": false, 
     "vote_average": 6.9 
    }, 
    { 
     "poster_path": "\/unPB1iyEeTBcKiLg8W083rlViFH.jpg", 
     "adult": false, 
     "overview": "A story about how a new baby's arrival impacts a family, told from the point of view of a delightfully unreliable narrator, a wildly imaginative 7 year old named Tim.", 
     "release_date": "2017-03-23", 
     "genre_ids": [ 
     16, 
     35, 
     10751 
     ], 
     "id": 295693, 
     "original_title": "The Boss Baby", 
     "original_language": "en", 
     "title": "The Boss Baby", 
     "backdrop_path": "\/bTFeSwh07oX99ofpDI4O2WkiFJ.jpg", 
     "popularity": 138.856227, 
     "vote_count": 649, 
     "video": false, 
     "vote_average": 5.7 
    }, 

です今度はAPI呼び出しを以下のようにして、URLを生成してinstanを作成するために書いたクラスを作成しますこれらのクラスは、URLを生成してAPIを呼び出すために使用しています。

ApiClient.java package com.example.vikas.movi​​e.rest;そのためDapterクラスは今

package com.example.vikas.movie.adapter; 

/** 
* Created by vikas on 23/4/17. 
*/ 
import android.content.Context; 
import android.support.v7.widget.RecyclerView; 
import android.text.TextUtils; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ImageView; 
import android.widget.LinearLayout; 
import android.widget.RelativeLayout; 
import android.widget.TextView; 

import com.bumptech.glide.Glide; 
import com.bumptech.glide.load.engine.DiskCacheStrategy; 
import com.example.vikas.movie.R; 
import com.example.vikas.movie.helper.CircleTransformation; 
import com.example.vikas.movie.model.Movie; 

import java.util.List; 
public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.MovieViewHolder> { 

    private List<Movie> movies; 
    private int rowLayout; 
    private Context context; 


    public static class MovieViewHolder extends RecyclerView.ViewHolder { 
     RelativeLayout moviesLayout; 
     TextView movieTitle; 
     TextView data; 
     TextView movieDescription; 
     TextView rating; 


     public MovieViewHolder(View v) { 
      super(v); 
      moviesLayout = (RelativeLayout) v.findViewById(R.id.movie_layout); 
      movieTitle = (TextView) v.findViewById(R.id.title); 
      data = (TextView) v.findViewById(R.id.subtitle); 
      movieDescription = (TextView) v.findViewById(R.id.description); 
      rating = (TextView) v.findViewById(R.id.rating); 
     } 
    } 

    public MovieAdapter(List<Movie> movies, int rowLayout, Context context) { 
     this.movies = movies; 
     this.rowLayout = rowLayout; 
     this.context = context; 
    } 

    @Override 
    public MovieAdapter.MovieViewHolder onCreateViewHolder(ViewGroup parent, 
                  int viewType) { 
     View view = LayoutInflater.from(parent.getContext()).inflate(rowLayout, parent, false); 
     return new MovieViewHolder(view); 
    } 


    @Override 
    public void onBindViewHolder(MovieViewHolder holder, final int position) { 
     holder.movieTitle.setText(movies.get(position).getTitle()); 
     holder.data.setText(movies.get(position).getReleaseDate()); 
     holder.movieDescription.setText(movies.get(position).getOverview()); 
     holder.rating.setText(movies.get(position).getvote_average().toString()); 
    } 

    @Override 
    public int getItemCount() { 
     return movies.size(); 
    } 
} 

MainActivityクラスMovieAdapter.java

あるので

/** 
* Created by vikas on 22/4/17. 
*/ 
import retrofit2.Retrofit; 
import retrofit2.converter.gson.GsonConverterFactory; 
public class ApiClient 
{ 
    public static final String URL="http://api.themoviedb.org/3/"; 
    private static Retrofit retrofit=null; 

    public static Retrofit getClient() 
    { 
     if(retrofit==null) 
     { 
      retrofit= new Retrofit.Builder()//netsed class of Retrofit used to create a new instance of retrofit class 
        .baseUrl(URL)//loaded the base URL which will be used later for all api calls 
        .addConverterFactory(GsonConverterFactory.create())//added converter factory for 
        // serialization and desserialization of objects 

        .build();//created the retrofit instance with configured values 

     } 
     return retrofit; 
    } 

} 
ApiInterface.java

package com.example.vikas.movie.rest; 

/** 
* Created by vikas on 23/4/17. 
*/ 
import com.example.vikas.movie.model.MoviesResponse; 
import retrofit2.Call; 
import retrofit2.http.GET; 
import retrofit2.http.Path; 
import retrofit2.http.Query; 
// to define endpoints of a URL we will use special retrofit annotations. we have used Get annotation in 
// to get information from the API and the parameters os this method are @Query,@Path, 
public interface ApiInterface 
{ 
    @GET("movie/now-playing") 
    Call<MoviesResponse> getNowPlayingMovies(@Query("api_key") String apikey); 
    //return value is alwayays a parameterized call<T> oject whose paremeter is generic so we can have 
    @GET("movie/{id}") 
    Call<MoviesResponse> getMovieDetails(@Path("id") int id, @Query("api_key") String apiKey); 
} 


// so using this we will generate the following URL 
//http://api.themoviedb.org/3/movie/now-playing?api_key=Xxxx 

と今私はRecyclerViewで結果を表示しています私はAPIへの呼び出しを行い、結果を取得して結果をアダプティブに与えるR

MainActivity.java

package com.example.vikas.movie; 

import android.support.design.widget.CoordinatorLayout; 
import android.support.design.widget.Snackbar; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.support.v7.widget.DefaultItemAnimator; 
import android.support.v7.widget.LinearLayoutManager; 
import android.support.v7.widget.RecyclerView; 
import android.util.Log; 


import com.example.vikas.movie.adapter.MovieAdapter; 
import com.example.vikas.movie.model.Movie; 
import com.example.vikas.movie.model.MoviesResponse; 
import com.example.vikas.movie.rest.ApiClient; 
import com.example.vikas.movie.rest.ApiInterface; 

import java.util.ArrayList; 
import java.util.List; 

import retrofit2.Call; 
import retrofit2.Callback; 
import retrofit2.Response; 

public class MainActivity extends AppCompatActivity 
{ 

    private static final String TAG=MainActivity.class.getSimpleName(); 
    //get which got from web API 
    private final static String API_KEY="Xxxxxx"; 
    private CoordinatorLayout coordinatorLayout; 
    private MovieAdapter movieAdapter; 
    private RecyclerView recyclerView; 
    private List<Movie> movieList = new ArrayList<>(); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     coordinatorLayout=(CoordinatorLayout)findViewById(R.id.coordinate_layout); 

     if(API_KEY.isEmpty()) 
     { 
      Snackbar snackbar = Snackbar 
        .make(coordinatorLayout, "Please Enter The key", Snackbar.LENGTH_LONG); 

      snackbar.show(); 
      return; 
     } 
     recyclerView = (RecyclerView) findViewById(R.id.recycler_view); 
     recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext())); 
     recyclerView.setItemAnimator(new DefaultItemAnimator()); 
     recyclerView.setAdapter(new MovieAdapter(movieList, R.layout.recyclerview_item_movie, getApplicationContext())); 


     ApiInterface apiInterface= ApiClient.getClient().create(ApiInterface.class); 
     Call<MoviesResponse> call= apiInterface.getNowPlayingMovies(API_KEY); 
     call.enqueue(new Callback<MoviesResponse>() 
     { 
      @Override 
      public void onResponse(Call<MoviesResponse> call, Response<MoviesResponse> response) 
      { 
       Log.d(TAG, "Number of movies received: " + movieList.size()); 
       int statusCode=response.code(); 
       movieList= response.body().getResults(); 
       movieAdapter.notifyDataSetChanged(); 


      } 

      @Override 
      public void onFailure(Call<MoviesResponse> call, Throwable t) 
      { 
       Snackbar snackbar = Snackbar 
         .make(coordinatorLayout, "Please Check your Internet Connection", Snackbar.LENGTH_LONG); 

       snackbar.show(); 
       Log.e(TAG, t.toString()); 

      } 
     }); 

    } 
} 

しかし、私はこのコードを実行している私は私がこのコードを実行するために今やるとする結果を取得する必要があり

04-23 23:32:32.529 30506-30506/com.example.vikas.movie E/AndroidRuntime: FATAL EXCEPTION: main 
                    Process: com.example.vikas.movie, PID: 30506 
                    java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.vikas.movie.adapter.MovieAdapter.notifyDataSetChanged()' on a null object reference 
                     at com.example.vikas.movie.MainActivity$1.onResponse(MainActivity.java:69) 
                     at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:68) 
                     at android.os.Handler.handleCallback(Handler.java:739) 
                     at android.os.Handler.dispatchMessage(Handler.java:95) 
                     at android.os.Looper.loop(Looper.java:148) 
                     at android.app.ActivityThread.main(ActivityThread.java:5417) 
                     at java.lang.reflect.Method.invoke(Native Method) 
                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

logcatこのエラーを取得していますnullを返さないように結果を正常に表示する

この質問は最初とは異なります。正しいURLを指定できませんでした

+0

を再作成する必要がありますので、それ以外の場合はnotifyDataSetChangedは何もしないあなたはいつも...私はしばらくの間 –

答えて

0

まず、あなたのURLが間違っています。それはhttps://developers.themoviedb.org/3/movies/get-now-playing

でこれが文書化されて

を今すぐプレイング代わりの映画/また、あなたがあなたの後にリストのサイズを取得することができnow_playing/

http://api.themoviedb.org/3/movie/now_playing?api_key=ddfffa28b4ace50cacf67274370469a1 

お知らせエンドポイント映画でなければなりません応答を得てリストを初期化する

最初にこの

その後、

Log.d(TAG, "Number of movies received: " + movieList.size()); 

EDIT:

はあなたがを初期化することはありません。この

recyclerView.setAdapter(new MovieAdapter(movieList, R.layout.recyclerview_item_movie, getApplicationContext())); 

を持っていて、notifyDataSetChanged()を呼び出すときに、はnullです。

movieAdapter = new MovieAdapter(movieList, R.layout.recyclerview_item_movie, getApplicationContext()); 

その後

recyclerView.setAdapter(movieAdapter); 

ノートへ

変更それは便利ではないかもしれませんが、UIに関連したほとんどのケースであるgetApplicationContext()を取得します。活動状況が好ましい

編集2:同じリストに項目を追加してから、notifyDataSetChanged()を下記のコメントのように呼び出す必要があります。

+0

待つために、あなたのスタックトレースポイントオブジェクトを初期化し、同じようにNullPointerExceptionが修正しますあなたの答えを試してください – Vikas

+0

あなたはブラウザでURLを貼り付けることができますかどうかを確認するために働いている。アンドロイドでそれを実行する必要はありません... – Raghunandan

+0

私はあなたの答えを試してみましたが、今度はムービーサイズ20を表示していますが、このlogcatエラーとアプリケーションのクラッシュを受けています – Vikas

0

movieAdapter = new MovieAdapter(movieList, R.layout.recyclerview_item_movie, this); 
recyclerView.setAdapter(movieAdapter); 

recyclerView.setAdapter(new MovieAdapter(movieList, R.layout.recyclerview_item_movie, getApplicationContext())); 

を交換し、これにより

movieList= response.body().getResults(); 
movieAdapter.notifyDataSetChanged(); 

を交換してください。あなたは完全に別のリストを持っており、アダプタ

movieList.clear(); 
movieList.addAll(response.body().getResults()); 
movieAdapter.notifyDataSetChanged(); 
+0

あなたは私たちが全く異なるリスト – Vikas

+0

これは '='がJavaでどのように動作するのか?新しいリストオブジェクトの参照を変数に代入しています。 –

+0

ありがとう – Vikas

関連する問題