Implementing Parcelable Class That Requires Contex

2019-02-13 12:12发布

问题:

I'd like for my data class to implement Parcelable so it can be shared between Activities, however it also needs reference to Context so the fields can be saved to SQLiteDatabase.

This however is a problem since Parcelable.Creator method createFromParcel only has one parameter Parcel.

public abstract class Record implements Parcelable {

protected Context context;
protected String value;

public Record(Context context) {
    this.context = context;
}

public Record(Parcel parcel) {
    this.value = parcel.readString();
}

public void save() {
    //save to SQLiteDatabase which requires Context
}

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

@Override
public void writeToParcel(Parcel parcel, int flag) {
    parcel.writeString(value);
}

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

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

How can a class that implements Parcelable also reference Context so it save to SQLiteDatabase?

回答1:

The Parcelable interface is like the Java interface Serializable. Objects which implement this interface should be serializable. This means it should be possible to transform the object to a representation which could be saved in a file e.g.

It is easily possible for a string, int, float or double etc, because they all have a string representation. The Context class is clearly not serializable and not parcelable, because it can be an Activity for example.

If you want to save the state of your activity to a database, you should find another way to do that.



回答2:

Your Record class probably doesn't really need access to the SQL database. The reason for it is exactly the problem you have now: it's very difficult to inject the Context back into each Record.

Perhaps a better solution would be to implement a static RecordSQLService, that has method save(Record r). Your app could start RecordSQLService when the app launches, so it will remain alive as long as your app does, and it takes the responsibility of saving away from the Record class, which makes it so you don't need Context anymore and can Parcel it.