java.lang.NullPointerException:尝试使用片段在空对象引用上调用接口方法'int java.util.List.size()'

时间:2018-07-12 07:50:10

标签: java android

我正在创建将使用TMDb API的电影列表应用程序。我创建了两个spearate片段,分别调用了api方法。

有一个java.lang.NullPointerException:尝试在出现空对象引用错误时调用接口方法'int java.util.List.size()'。 这是我的错误代码:

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: sg.edu.tp.moviex, PID: 6404
              java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
                  at sg.edu.tp.moviex.Adapter.MoviesAdapter.getItemCount(MoviesAdapter.java:56)
                  at android.support.v7.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:3722)
                  at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3527)
                  at android.support.v7.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:1737)
                  at android.support.v7.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:4928)
                  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
                  at android.view.Choreographer.doCallbacks(Choreographer.java:723)
                  at android.view.Choreographer.doFrame(Choreographer.java:655)
                  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
                  at android.os.Handler.handleCallback(Handler.java:790)
                  at android.os.Handler.dispatchMessage(Handler.java:99)
                  at android.os.Looper.loop(Looper.java:164)
                  at android.app.ActivityThread.main(ActivityThread.java:6494)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
                  at com.android.internal.os.ZygoteInit.main    

这是片段Java代码:

public class LatestBlockbustersFragment extends Fragment {

View view;
private RecyclerView recyclerView1;
private MoviesAdapter moviesAdapter;
private List<Movie> movieList;
private SwipeRefreshLayout swipeContainer1;
public static final String LOG_TAG = MoviesAdapter.class.getName();

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState){
    view = inflater.inflate(R.layout.fragment_home, container, false);
    initViews();
    return view;
}

@Override
public void onCreate(@Nullable Bundle SavedInstanceState){
    super.onCreate(SavedInstanceState);

    movieList = new ArrayList<>();
}

private void loadJSON(){
    try {
        if (BuildConfig.THE_MOVIE_DB_API_TOKEN.isEmpty()) {
            Toast.makeText(getActivity(), "Please obtain API key from themoviedb.org", Toast.LENGTH_SHORT).show();
            return;
        }
        Client Client = new Client();

        Service apiService = Client.getClient().create(Service.class);

        // API service: getLatestMovies ; change to other forms to get other types
        Call<MovieResponse> call = apiService.getLatestMovies(BuildConfig.THE_MOVIE_DB_API_TOKEN);
        call.enqueue(new Callback<MovieResponse>() {
            @Override
            public void onResponse(Call<MovieResponse> call, Response<MovieResponse> response) {
                List<Movie> movies = response.body().getResults();
                recyclerView1.setAdapter(new MoviesAdapter(getActivity(), movies));
                recyclerView1.smoothScrollToPosition(0);
                if (swipeContainer1.isRefreshing()){
                    swipeContainer1.setRefreshing(false);
                }

            }

            @Override
            public void onFailure(Call<MovieResponse> call, Throwable t) {
                Log.d("Error", t.getMessage());
                Toast.makeText(getActivity(), "Error Fetching Data!", Toast.LENGTH_SHORT).show();
            }
        });


    } catch (Exception e) {
        Log.d("Error", e.getMessage());
        Toast.makeText(getActivity(), e.toString(), Toast.LENGTH_SHORT).show();
    }
}


private void initViews(){

    recyclerView1 = view.findViewById(R.id.recycler_view);
    movieList = new ArrayList<>();
    moviesAdapter = new MoviesAdapter(getActivity(), movieList);

    recyclerView1.setLayoutManager(new GridLayoutManager(getActivity(),2));
    recyclerView1.setItemAnimator(new DefaultItemAnimator());
    recyclerView1.setAdapter(moviesAdapter);
    moviesAdapter.notifyDataSetChanged();

    loadJSON();

    //TODO Look at SwipeRefreshLayout and Lambda Expressions

    swipeContainer1 = view.findViewById(R.id.swipeContainer);
    swipeContainer1.setColorSchemeResources(android.R.color.holo_orange_dark);
    swipeContainer1.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            initViews();
        }
    });

}

这是MovieAdapter代码,其中错误是:

import android.content.Context;
import android.content.Intent;
import android.support.v7.widget.RecyclerView;
import android.telecom.Call;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.bumptech.glide.Glide;

import java.util.List;

import sg.edu.tp.moviex.Activities.MovieDetailActivity;
import sg.edu.tp.moviex.Model.Movie;
import sg.edu.tp.moviex.R;

public class MoviesAdapter extends       RecyclerView.Adapter<MoviesAdapter.MyViewHolder> {

private Context mContext;
private List<Movie> movieList;

public MoviesAdapter(Context mContext, List<Movie> movieList){
    this.mContext = mContext;
    this.movieList = movieList;
}

// int i refers to the count/position

@Override
public MoviesAdapter.MyViewHolder onCreateViewHolder(ViewGroup viewGroup, int i){
    View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.movie_card, viewGroup, false);

    return new MyViewHolder(view);
}


@Override
public void onBindViewHolder(final MoviesAdapter.MyViewHolder viewHolder, int i){
    // Calls getOriginalTitle from movie.java and sets as movie title
    viewHolder.title.setText(movieList.get(i).getOriginalTitle());
    // Calls getVoteAverage from movie.java and sets to userrating
    String vote = Double.toString(movieList.get(i).getVoteAverage());
    viewHolder.userrating.setText(vote);
    // Calls getPosterPath from movie.java and sets poster as thumbnail
    Glide.with(mContext).load(movieList.get(i).getPosterPath())
            .placeholder(R.drawable.load).into(viewHolder.thumbnail);
}


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

public class MyViewHolder extends RecyclerView.ViewHolder{

    public TextView title, userrating;
    public ImageView thumbnail;

    public MyViewHolder(View view){
        super(view);
        title = view.findViewById(R.id.title);
        userrating = view.findViewById(R.id.userrating);
        thumbnail = view.findViewById(R.id.thumbnail);

        view.setOnClickListener(v -> {
            int position = getAdapterPosition();
            if (position != RecyclerView.NO_POSITION){
                Movie clickedDataItem = movieList.get(position);
                Intent intent = new Intent(mContext, MovieDetailActivity.class);
                intent.putExtra("original_title", movieList.get(position).getOriginalTitle());
                intent.putExtra("poster_path", movieList.get(position).getPosterPath());
                intent.putExtra("overview", movieList.get(position).getOverview());
                intent.putExtra("vote_average",Double.toString(movieList.get(position).getVoteAverage()));
                intent.putExtra("release_date", movieList.get(position).getReleaseDate());
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                mContext.startActivity(intent);
                Toast.makeText(v.getContext(), "You clicked" + clickedDataItem.getOriginalTitle(), Toast.LENGTH_SHORT).show();
            }
        });
    }
}

请帮助。预先感谢。

1 个答案:

答案 0 :(得分:0)

在片段中,您必须将电影添加到movieList

movieList.add(movies);

我建议您在API响应中执行以下操作:

  try {
                    JSONObject job = new JSONObject(response);
                    if (movieList != null) {
                        movieList.clear();
                    }
                        JSONArray jarray = job.getJSONArray("whatever array name");
                        if (jarray.length() > 0) {
                            for (int i = 0; i < jarray.length(); i++) {
                         JSONObject json_obj = jarray.getJSONObject(i);
                         Movies type = new Movies();
                         type.setOriginalTitle(json_obj.getString("parameter name"));
                         type.setVoteAverage(json_obj.getString("parameter name"));
                         type.setPosterPath(json_obj.getString("parameter name"));

                         movieList.add(type);
                            }

                      if (movieList != null) {
                      Log.d("asher","movie list "+movieList);
                      MoviesAdapter adapter = new MoviesAdapter(activity, movieList);
                      recyclerView1.setAdapter(adapter);
                            }

                        }
                } catch (JSONException e) {
                    e.printStackTrace();
                }

现在在适配器类中,您可以通过onBindViewHolder()中的位置获取它。 将Log放入您的onBindViewHolder方法中,然后检查是否所有数据都在传输。 并在fragment类中执行相同的操作,在将movieList设置为适配器之前,将其放入日志。