Reputation: 5017
I have a class called MusicFile, its constructor is:
protected MusicFile(Parcel in) {
Title = in.readString();
Album = in.readString();
Artist = in.readString();
Path = in.readString();
Genre = in.readString();
Data = in.readString();
artistID = in.readInt();
if (in.readByte() == 0) {
AlbumID = null;
} else {
AlbumID = in.readLong();
}
albumCover = in.readParcelable(Uri.class.getClassLoader());
}
But now that I've made it to extend Parcelable
, I cannot just create a new MusicFile
like so:
MusicFile musicFile = new MusicFile();
Because it requires Parcel In
.
How can I create a new Music file now? I've tried the following:
` Parcel parcel = New Parcel();
MusicFile musicFile = new MusicFile(parcel); `
However that doesnt seem to work. I get the following error: 'Parcel(long)' is not public in 'android.os.Parcel'. Cannot be accessed from outside package
What is the correct way to do this?
Upvotes: 0
Views: 2915
Reputation: 1311
You can use Parcel.obtain() to get a Parcel
. Don't forget to do
parcel.recycle()
after finishing using it.
Upvotes: 3
Reputation: 2916
You can extend Parcelable
and leave your default constructor
import android.os.Parcel;
import android.os.Parcelable;
public class MusicFile implements Parcelable {
private Integer id;
private String title;
...
public MusicFile(Integer id, String title) {
this.id = id;
this.title = title;
}
public MusicFile(){
}
protected MusicFile(Parcel in) {
id = in.readByte() == 0x00 ? null : in.readInt();
title = in.readString();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
if (id == null) {
dest.writeByte((byte) (0x00));
} else {
dest.writeByte((byte) (0x01));
dest.writeInt(id);
}
dest.writeString(title);
}
@SuppressWarnings("unused")
public static final Parcelable.Creator<MusicFile> CREATOR = new Parcelable.Creator<MusicFile>() {
@Override
public MusicFile createFromParcel(Parcel in) {
return new MusicFile(in);
}
@Override
public MusicFile[] newArray(int size) {
return new MusicFile[size];
}
};
}
The class Parcel
is handled by Android when you pass objects in bundles like bundle.addParcelableExtra(...)
. You should not attempt to handle these things on your own. When you call addParcelableExtra()
Android uses these methods (writeToParcel
, describeContents
, etc.) to serialize your objects, but it is completely up to the framework. You should add these methods to help Android serialize your objects automatically (and save you from a lot of pain) but you keep your standards constructors, getters/setters, etc.
Upvotes: 1
Reputation: 6426
You need to create an empty constructor for parcelable. Your model should now look something like this:
public static final Creator<MusicFile> CREATOR = new Creator<MusicFile>() {
@Override
public MusicFilecreateFromParcel(Parcel in) {
return new MusicFile(in);
}
@Override
public ClassModelInfo[] newArray(int size) {
return new ClassModelInfo[size];
}
};
// It's an empty constructor for parcelable
private MusicFile() {
}
// This constructor is what parcel generates.
protected MusicFile(Parcel in) {
Title = in.readString();
Album = in.readString();
Artist = in.readString();
Path = in.readString();
Genre = in.readString();
Data = in.readString();
artistID = in.readInt();
if (in.readByte() == 0) {
AlbumID = null;
} else {
AlbumID = in.readLong();
}
albumCover = in.readParcelable(Uri.class.getClassLoader());
}
Upvotes: 0