无法通过 intent extras 传递对象数组

Unable to pass array of objects via intent extras

我正在通过意图将电影对象的 ArrayList 从 MainActivity 传递到 DetailActivity

intent.putExtra(KEY_mFavoriteMovies, mFavoriteMovies);
startActivity(intent);

在另一个 activity 中,我添加了额外的电影对象。

mFavoriteMovies(movie);

但是,MainActivity 中的 mFavoriteMovies 似乎不包含其他电影对象。

这种行为是预期的吗?

方法取决于什么是电影列表...

  • 如果你的电影列表是一个简单的字符串数组列表,那么使用 putStringArrayListExtragetStringArrayListExtra.
  • 如果它们是对象(分开class)那么你应该实现 可打包并使用 putParcelableArrayListExtragetParcelableArrayList.

如果 MovieName 是 Object/Class 则执行 Parcelable

import android.os.Parcel;
import android.os.Parcelable;

public class MovieName implements Parcelable {

    private String name;

    private String year;

    public MovieName(String name, String year) {
        this.name = name;
        this.year = year;
    }

    public MovieName(Parcel in) {
        name = in.readString();
        year = in.readString();
    }

    // Creator
    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        public MovieName createFromParcel(Parcel in) {
            return new MovieName(in);
        }

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

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

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(name);
        parcel.writeString(year);
    }

    @Override
    public String toString() {
        return "MovieName=[name=" + name + ";year=" + year + "]";
    }
}

里面 MainActivity 当你正要 startActivityDetailActivity

Intent intent = new Intent(view.getContext(), DetailActivity.class);

ArrayList<String> movieNames = new ArrayList<String>();
movieNames.add("Star Wars");
movieNames.add("Transporter");
movieNames.add("Need for Speed");
intent.putStringArrayListExtra("MOVIE_NAMES", movieNames);
Log.d("Movie Names", "Writing into intent ... " + movieNames.toString());

ArrayList<MovieName> movieNameList = new ArrayList<MovieName>();
movieNameList.add(new MovieName("Star Wars", "1900"));
movieNameList.add(new MovieName("Transporter", "2000"));
intent.putParcelableArrayListExtra("movie", movieNameList);
Log.d("MovieName Parcelable", "Writing into intent ... " + movieNameList.toString());

startActivity(intent);

里面DetailActivity's onCreate

ArrayList<String> movieNames = getIntent().getStringArrayListExtra("MOVIE_NAMES");
Log.d("Movie Names", "Reading from intent ... " + movieNames.toString());

ArrayList<MovieName> movieNameList = getIntent().getExtras().getParcelableArrayList("movie");
Log.d("MovieName Parcelable", "Reading from intent ... " + movieNameList.toString());

样本运行

07-25 16:32:53.108 5264-5264/? D/Movie Names: Writing into intent ... [Star Wars, Transporter, Need for Speed]
07-25 16:32:53.111 5264-5264/? D/MovieName Parcelable: Writing into intent ... [MovieName=[name=Star Wars;year=1900], MovieName=[name=Transporter;year=2000]]

07-25 16:32:53.144 5264-5264/? D/Movie Names: Reading from intent ... [Star Wars, Transporter, Need for Speed]
07-25 16:32:53.145 5264-5264/? D/MovieName Parcelable: Reading from intent ... [MovieName=[name=Star Wars;year=1900], MovieName=[name=Transporter;year=2000]]

除了@JRG 的回答之外,为了在 MainActivity 中获得更新的列表,您需要以 startActivityForResult 开始您的 DetailActivity。这将为您提供一个选项,通过 onActivityResult 回调从 DetailsActivity 更新数组 setResultMainActivity

另一种方法是通过将视图部分(活动)与模型(最喜欢的电影)分开来更改应用程序的体系结构来修复它。

这是预期的行为,因为当您在 DetailActivity 处修改数组列表时,您正在使用电影列表的不同实例。

您可以通过从 startActivityForResult 开始 DetailActivity 然后将更新后的列表发送回您的 MainActivity

来获取您对列表所做的更改

你的 MainActivity

会有这样的东西
ArrayList<String> mMovies;
int DETAIL_REQUEST_CODE = 123;
String KEY_FAVORITE_MOVIES = "key-movies";

private void startDetailActivity() {
    Intent intent = new Intent(this, DetailActivity.class);
    intent.putStringArrayListExtra(KEY_FAVORITE_MOVIES, mMovies);
    startActivityForResult(intent, DETAIL_REQUEST_CODE);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == DETAIL_REQUEST_CODE && resultCode == RESULT_OK) {
        mMovies = data.getStringArrayListExtra(KEY_FAVORITE_MOVIES);
    }
}

并且您必须从 DetailActivity 发送更新后的列表,内容如下:

public void finishDetail() {
    Intent resultIntent = new Intent();
    resultIntent.putStringArrayListExtra(KEY_FAVORITE_MOVIES, mMovies);
    setResult(Activity.RESULT_OK, resultIntent);
    finish();
}