Android如何将整个ArrayList传递到另一个Activity,跳转崩溃如何解决?
崩溃原因
你遇到的报错是Intent传递自定义对象集合时序列化失败,Android系统的Parcel机制无法序列化你自定义的AudioModel类,因为该类没有实现Parcelable接口,这是Intent在组件间传递自定义对象的强制要求。
修复方案
1. 让AudioModel实现Parcelable接口
修改你的AudioModel类代码,示例实现如下:
public class AudioModel implements Parcelable { private String aName; private String aPath; private String aAlbum; private String albumart; // 你原来的构造方法、get、set方法保留不变 public AudioModel(String aName, String aPath, String aAlbum, String albumart) { this.aName = aName; this.aPath = aPath; this.aAlbum = aAlbum; this.albumart = albumart; } protected AudioModel(Parcel in) { aName = in.readString(); aPath = in.readString(); aAlbum = in.readString(); albumart = in.readString(); } public static final Creator<AudioModel> CREATOR = new Creator<AudioModel>() { @Override public AudioModel createFromParcel(Parcel in) { return new AudioModel(in); } @Override public AudioModel[] newArray(int size) { return new AudioModel[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(aName); dest.writeString(aPath); dest.writeString(aAlbum); dest.writeString(albumart); } // 你原来的getter方法保留 public String getaName() { return aName; } public String getaPath() { return aPath; } public String getaAlbum() { return aAlbum; } public String getAlbumart() { return albumart; } }
如果你的AudioModel还有其他字段,记得在writeToParcel和Parcel构造方法里同步添加读写逻辑,顺序要保持一致。
2. 修正Adapter中Intent传值的错误
你原来传递POSITION时传的是对象的toString(),实际应该传递当前点击的下标int值:
@Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { AudioModel currentSong = arrayList.get(position); holder.name.setText(currentSong.getaName()); holder.album.setText(currentSong.getaAlbum()); holder.imageView.setImageBitmap(BitmapFactory.decodeFile(currentSong.getAlbumart())); holder.imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent in = new Intent(context,PlayerActivity.class); // 单个字段可以不用传,后面直接从list取就行,这里保留也不影响 in.putExtra("SONG",currentSong.getaName()); in.putExtra("PATH",currentSong.getaPath()); in.putExtra("ALBUM",currentSong.getaAlbum()); in.putParcelableArrayListExtra("LIST",arrayList); // 修正:传递int类型的位置下标 in.putExtra("POSITION", position); context.startActivity(in); } }); }
3. 修正PlayerActivity的取值逻辑
public class PlayerActivity extends AppCompatActivity { TextView songanme, songAlbum,duration,movetime; ImageView playbutton,nextbtn,previousbtn; SeekBar seekBar; MediaPlayer mediaPlayer ; ArrayList<AudioModel> list; int CURRENT_POSITION ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_player); songanme = findViewById(R.id.music_name_pl); movetime = findViewById(R.id.move_time); seekBar = findViewById(R.id.seekBar); songAlbum = findViewById(R.id.music_album_pl); duration = findViewById(R.id.duration); playbutton = findViewById(R.id.play_btn_pl); nextbtn = findViewById(R.id.next_btn_pl); previousbtn = findViewById(R.id.previous_pl); songanme.setSelected(true); Intent intent = getIntent(); // 直接从Intent取Parcelable集合 list = intent.getParcelableArrayListExtra("LIST"); // 取位置下标 CURRENT_POSITION = intent.getIntExtra("POSITION",0); // 后面直接用list.get(CURRENT_POSITION)就能拿到当前点击的歌曲信息 } }
内容的提问来源于stack exchange,提问作者Vikram Choudhary
相关产品推荐
相关产品推荐

