java - 通过 parcelable extra 检索时为空对象

标签 java android parcelable

构建一个调用 api 并检索数据以在构建初始网格布局等并调用 api 后显示流行电影的 MoviesDB 应用程序我构建了另一个 Activity 来显示单击的项目。我只想在对 Activity 进行编码之前记录一些数据,但它返回 null。这是一个自定义的 Movie 对象。我已经阅读了一些内容,似乎 Movie.class 中 parcelable 的排序有问题,但我不确定。

请帮忙(如果你也能详细说明那就太好了)

public class MovieActivity extends AppCompatActivity {

    private Movie movie;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_movie);
//        getSupportActionBar().setTitle("Movie");
//        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        Intent intent = getIntent();

        if(intent.hasExtra("movie")) {
            movie = intent.getParcelableExtra("movie");
            Toast.makeText(getApplicationContext(), movie.getOriginalTitle(), Toast.LENGTH_LONG).show();
        }
    }

}

public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.MovieViewHolder> {

    private Context context;
    private ArrayList<Movie> movieArrayList;

    public MovieAdapter(Context context, ArrayList<Movie> movieArrayList) {
        this.context = context;
        this.movieArrayList = movieArrayList;
    }

    @NonNull
    @Override
    public MovieViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {


        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.movie_list_item, parent, false);
        return new MovieViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull MovieViewHolder holder, int position) {

        holder.movieTitle.setText(movieArrayList.get(position).getOriginalTitle());
        holder.rate.setText(Double.toString(movieArrayList.get(position).getVoteAverage()));

        String imagePath = "https://image.tmdb.org/t/p/w500" + movieArrayList.get(position).getPosterPath();

        Glide.with(context)
                .load(imagePath)
                .placeholder(R.drawable.loading)
                .into(holder.movieImage);


    }

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


    public class MovieViewHolder extends RecyclerView.ViewHolder {


        public TextView movieTitle, rate;
        public ImageView movieImage;

        public MovieViewHolder(View itemView) {
            super(itemView);

            movieImage = (ImageView) itemView.findViewById(R.id.ivMovie);
            rate = (TextView) itemView.findViewById(R.id.tvRating);
            movieTitle = (TextView) itemView.findViewById(R.id.tvTitle);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {

                    int position = getAdapterPosition();

                    if (position != RecyclerView.NO_POSITION) {

                        Movie selctedMovie = movieArrayList.get(position);

                        Intent intent = new Intent(context, MovieActivity.class);
                        intent.putExtra("movie", selctedMovie);
                        context.startActivity(intent);


                    }


                }
            });


        }
    }
}

public class Movie implements Parcelable
{

    @SerializedName("vote_count")
    @Expose
    private Integer voteCount;
    @SerializedName("id")
    @Expose
    private Integer id;
    @SerializedName("video")
    @Expose
    private Boolean video;
    @SerializedName("vote_average")
    @Expose
    private Double voteAverage;
    @SerializedName("title")
    @Expose
    private String title;
    @SerializedName("popularity")
    @Expose
    private Double popularity;
    @SerializedName("poster_path")
    @Expose
    private String posterPath;
    @SerializedName("original_language")
    @Expose
    private String originalLanguage;
    @SerializedName("original_title")
    @Expose
    private String originalTitle;
    @SerializedName("genre_ids")
    @Expose
    private List<Integer> genreIds = null;
    @SerializedName("backdrop_path")
    @Expose
    private String backdropPath;
    @SerializedName("adult")
    @Expose
    private Boolean adult;
    @SerializedName("overview")
    @Expose
    private String overview;
    @SerializedName("release_date")
    @Expose
    private String releaseDate;
    public final static Parcelable.Creator<Movie> CREATOR = new Creator<Movie>() {


        @SuppressWarnings({
                "unchecked"
        })
        public Movie createFromParcel(Parcel in) {
            return new Movie(in);
        }

        public Movie[] newArray(int size) {
            return (new Movie[size]);
        }

    }
            ;

    protected Movie(Parcel in) {
        this.voteCount = ((Integer) in.readValue((Integer.class.getClassLoader())));
        this.id = ((Integer) in.readValue((Integer.class.getClassLoader())));
        this.video = ((Boolean) in.readValue((Boolean.class.getClassLoader())));
        this.voteAverage = ((Double) in.readValue((Double.class.getClassLoader())));
        this.title = ((String) in.readValue((String.class.getClassLoader())));
        this.popularity = ((Double) in.readValue((Double.class.getClassLoader())));
        this.posterPath = ((String) in.readValue((String.class.getClassLoader())));
        this.originalLanguage = ((String) in.readValue((String.class.getClassLoader())));
        this.originalTitle = ((String) in.readValue((String.class.getClassLoader())));
        in.readList(this.genreIds, (java.lang.Integer.class.getClassLoader()));
        this.backdropPath = ((String) in.readValue((String.class.getClassLoader())));
        this.adult = ((Boolean) in.readValue((Boolean.class.getClassLoader())));
        this.overview = ((String) in.readValue((String.class.getClassLoader())));
        this.releaseDate = ((String) in.readValue((String.class.getClassLoader())));
    }

    public Movie() {
    }

    public Integer getVoteCount() {
        return voteCount;
    }

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

    public Integer getId() {
        return id;
    }

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

    public Boolean getVideo() {
        return video;
    }

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

    public Double getVoteAverage() {
        return voteAverage;
    }

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

    public String getTitle() {
        return title;
    }

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

    public Double getPopularity() {
        return popularity;
    }

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

    public String getPosterPath() {
        return posterPath;
    }

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

    public String getOriginalLanguage() {
        return originalLanguage;
    }

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

    public String getOriginalTitle() {
        return originalTitle;
    }

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

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

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

    public String getBackdropPath() {
        return backdropPath;
    }

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

    public Boolean getAdult() {
        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 void writeToParcel(Parcel dest, int flags) {
        dest.writeValue(voteCount);
        dest.writeValue(id);
        dest.writeValue(video);
        dest.writeValue(voteAverage);
        dest.writeValue(title);
        dest.writeValue(popularity);
        dest.writeValue(posterPath);
        dest.writeValue(originalLanguage);
        dest.writeValue(originalTitle);
        dest.writeList(genreIds);
        dest.writeValue(backdropPath);
        dest.writeValue(adult);
        dest.writeValue(overview);
        dest.writeValue(releaseDate);
    }

    public int describeContents() {
        return 0;
    }

}

我很难理解,因为我预计通过使用 putExtra 并在调用 getIntent 时传递电影对象并尝试检索数据,它会返回 null 但经过大量调试后我可以看到它的 null 对象我已经过去了,这让我相信 parcelable 在某个地方是不正确的。

在 MainActivity 中显示所有电影,因此这不是 api key 的问题。

提前致谢。

最佳答案

我稍微重写了你的数据类。请试试这个:

public class Movie implements Parcelable {

@SerializedName("vote_count")
@Expose
private Integer voteCount;
@SerializedName("id")
@Expose
private Integer id;
@SerializedName("video")
@Expose
private Boolean video;
@SerializedName("vote_average")
@Expose
private Double voteAverage;
@SerializedName("title")
@Expose
private String title;
@SerializedName("popularity")
@Expose
private Double popularity;
@SerializedName("poster_path")
@Expose
private String posterPath;
@SerializedName("original_language")
@Expose
private String originalLanguage;
@SerializedName("original_title")
@Expose
private String originalTitle;
@SerializedName("genre_ids")
@Expose
private List<Integer> genreIds = null;
@SerializedName("backdrop_path")
@Expose
private String backdropPath;
@SerializedName("adult")
@Expose
private Boolean adult;
@SerializedName("overview")
@Expose
private String overview;
@SerializedName("release_date")
@Expose
private String releaseDate;

protected Movie(Parcel in) {
    voteCount = in.readByte() == 0x00 ? null : in.readInt();
    id = in.readByte() == 0x00 ? null : in.readInt();
    byte videoVal = in.readByte();
    video = videoVal == 0x02 ? null : videoVal != 0x00;
    voteAverage = in.readByte() == 0x00 ? null : in.readDouble();
    title = in.readString();
    popularity = in.readByte() == 0x00 ? null : in.readDouble();
    posterPath = in.readString();
    originalLanguage = in.readString();
    originalTitle = in.readString();
    if (in.readByte() == 0x01) {
        genreIds = new ArrayList<Integer>();
        in.readList(genreIds, Integer.class.getClassLoader());
    } else {
        genreIds = null;
    }
    backdropPath = in.readString();
    byte adultVal = in.readByte();
    adult = adultVal == 0x02 ? null : adultVal != 0x00;
    overview = in.readString();
    releaseDate = in.readString();
}

@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    if (voteCount == null) {
        dest.writeByte((byte) (0x00));
    } else {
        dest.writeByte((byte) (0x01));
        dest.writeInt(voteCount);
    }
    if (id == null) {
        dest.writeByte((byte) (0x00));
    } else {
        dest.writeByte((byte) (0x01));
        dest.writeInt(id);
    }
    if (video == null) {
        dest.writeByte((byte) (0x02));
    } else {
        dest.writeByte((byte) (video ? 0x01 : 0x00));
    }
    if (voteAverage == null) {
        dest.writeByte((byte) (0x00));
    } else {
        dest.writeByte((byte) (0x01));
        dest.writeDouble(voteAverage);
    }
    dest.writeString(title);
    if (popularity == null) {
        dest.writeByte((byte) (0x00));
    } else {
        dest.writeByte((byte) (0x01));
        dest.writeDouble(popularity);
    }
    dest.writeString(posterPath);
    dest.writeString(originalLanguage);
    dest.writeString(originalTitle);
    if (genreIds == null) {
        dest.writeByte((byte) (0x00));
    } else {
        dest.writeByte((byte) (0x01));
        dest.writeList(genreIds);
    }
    dest.writeString(backdropPath);
    if (adult == null) {
        dest.writeByte((byte) (0x02));
    } else {
        dest.writeByte((byte) (adult ? 0x01 : 0x00));
    }
    dest.writeString(overview);
    dest.writeString(releaseDate);
}

@SuppressWarnings("unused")
public static final Parcelable.Creator<Movie> CREATOR = new Parcelable.Creator<Movie>() {
    @Override
    public Movie createFromParcel(Parcel in) {
        return new Movie(in);
    }

    @Override
    public Movie[] newArray(int size) {
        return new Movie[size];
    }
};
}

关于java - 通过 parcelable extra 检索时为空对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56628643/

相关文章:

android - 文件或数据库

android - 提取 YouTube MP4 URL 是否算作视频的新观看次数

java - 用jsoup解析表数据

java - 如何使用用户输入的随机整数 x 数量填充数组?

android - 谁来更新android通知栏中的时间?

java - 可打包 writeToParcel() : What's the best way to write multiple variables of the same type?

android - intent.putExtra 一个 Parcelable 对象和枚举的列表

android.os.TransactionTooLargeException 随机抛出

java - Spring Boot hello world MVC 应用程序无法加载

Java多线程程序卡在对 map 的访问上