How to read and write Enum into parcel on Android?

后端 未结 6 726
旧时难觅i
旧时难觅i 2021-02-01 12:18

Here is my model class:

public enum Action {
    RETRY, SETTINGS
}

private int imageId;
private String description;
private String actionName;
private Action ac         


        
相关标签:
6条回答
  • 2021-02-01 12:55

    Any enum is serializable.

    You can do this in writeToParcel(): dest.writeSerializable(action)

    And in the constructor: action = (Action) in.readSerializable()

    0 讨论(0)
  • 2021-02-01 13:01

    Enum decleration:

    public enum Action {
    
        NEXT(1),
        OK(2);
    
        private int action;
    
        Action(int action) {
            this.action = action;
        }
    
    }
    

    Reading from Parcel:

    protected ActionParcel(Parcel in) {
        int actionTmp = in.readInt();
        action = Tutorials.Action.values()[actionTmp];
    }
    

    Writing to parcel:

    public void writeToParcel(Parcel dest, int flags) {
        int actionTmp = action == null ? -1 : action.ordinal();
        dest.writeInt(actionTmp);
    }
    
    0 讨论(0)
  • 2021-02-01 13:01

    Sample Kotlin-Code (null-safe):

    writeInt(action?.ordinal ?: -1)
    
    action = readInt().let { if (it >= 0) enumValues<MyEnum>()[it] else null }
    

    Which can be encapsulated in a write/readEnum Methods as extensions to Parcel:

    fun <T : Enum<T>> Parcel.writeEnum(value: T?) = 
        writeInt(value?.ordinal ?: -1)
    
    inline fun <reified T : Enum<T>> Parcel.readEnum(): T? = 
        readInt().let { if (it >= 0) enumValues<T>()[it] else null }
    
    0 讨论(0)
  • 2021-02-01 13:06

    One way to do this is to write Actions in integer and read them properly as integer and convert them into Action. What I mean:

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(this.imageId);
        dest.writeString(this.description);
        dest.writeString(this.actionName);
    
        int actionAsInt = action == Action.RETRY ? 1 : 0;
        dest.writeInt(actionAsInt);
    }
    
    protected NetworkError(Parcel in) {
        this.imageId = in.readInt();
        this.description = in.readString();
        this.actionName = in.readString();
    
        int actionAsInt = in.readInt();
        this.action = actionAsInt == 1 ? Action.RETRY : Action.SETTINGS;
    }
    

    Try it. Success ...

    0 讨论(0)
  • 2021-02-01 13:10

    I had similar problem and my solution was:

    parcel.writeString(this.questionType.name());
    

    and for reading :

    this.questionType = QuestionType.valueOf(parcel.readString());
    

    QuestionType is enum and remember that ordering of elements matters.

    0 讨论(0)
  • 2021-02-01 13:11

    The most efficient - memory efficient - bundle is created by using the ENUM ordinal value.

    Writing to Parcel dest.writeInt(enum_variable.ordinal());

    Reading from parcel enum_variable = EnumName.values()[in.readInt()];

    This should be fine unless you don't heed the documentation's admonitions:

    Parcel is not a general-purpose serialization mechanism. This class (and the corresponding Parcelable API for placing arbitrary objects into a Parcel) is designed as a high-performance IPC transport. As such, it is not appropriate to place any Parcel data in to persistent storage: changes in the underlying implementation of any of the data in the Parcel can render older data unreadable.

    In other words, you shouldn't pass Parcels between code versions because it may not work.

    0 讨论(0)
提交回复
热议问题