无法通过 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
似乎不包含其他电影对象。
这种行为是预期的吗?
方法取决于什么是电影列表...
- 如果你的电影列表是一个简单的字符串数组列表,那么使用
putStringArrayListExtra
和 getStringArrayListExtra
.
- 如果它们是对象(分开class)那么你应该实现
可打包并使用
putParcelableArrayListExtra
和
getParcelableArrayList
.
如果 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
当你正要 startActivity
去 DetailActivity
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
更新数组 setResult
到 MainActivity
。
另一种方法是通过将视图部分(活动)与模型(最喜欢的电影)分开来更改应用程序的体系结构来修复它。
这是预期的行为,因为当您在 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();
}
我正在通过意图将电影对象的 ArrayList 从 MainActivity
传递到 DetailActivity
。
intent.putExtra(KEY_mFavoriteMovies, mFavoriteMovies);
startActivity(intent);
在另一个 activity 中,我添加了额外的电影对象。
mFavoriteMovies(movie);
但是,MainActivity
中的 mFavoriteMovies
似乎不包含其他电影对象。
这种行为是预期的吗?
方法取决于什么是电影列表...
- 如果你的电影列表是一个简单的字符串数组列表,那么使用
putStringArrayListExtra
和getStringArrayListExtra
. - 如果它们是对象(分开class)那么你应该实现
可打包并使用
putParcelableArrayListExtra
和getParcelableArrayList
.
如果 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
当你正要 startActivity
去 DetailActivity
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
更新数组 setResult
到 MainActivity
。
另一种方法是通过将视图部分(活动)与模型(最喜欢的电影)分开来更改应用程序的体系结构来修复它。
这是预期的行为,因为当您在 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();
}