запись parcelable на enum приводит к сбою приложения - PullRequest
0 голосов
/ 25 октября 2019

Эта строка dest.writeParcelable(department, flags); вызывает сбой приложения, когда я выполняю посылку объекта через намерение.

Когда я комментирую строку, приложение проходит, но, конечно, у меня нет значения отдела.

public class User implements Parcelable {

    public String id;
    public String name;
    public String email;
    public Department department;

    // other implementations of Parcelable 

protected UserVO(Parcel in) {
    id = in.readString();
    name = in.readString();
    email = in.readString();
    department = in.readParcelable(Department.class.getClassLoader());
}


    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(id);
        dest.writeString(name);
        dest.writeString(email);
        dest.writeParcelable(department, flags); // crashes
    }
}

Отдел Enum

public enum Department implements Parcelable {

    SALES("Sales", 1),
    HR("Human Resources", 2),
    SHIPPING("Shipping", 3),

    public final String name;
    public final int ordinal;

    Department(String name, int ordinal) {
        this.name = name;
        this.ordinal = ordinal;
    }

    Department(Parcel in) {
        name = in.readString();
        ordinal = in.readInt();
    }

    public static final Creator<Department> CREATOR = new Creator<Department>() {
        @Override
        public Department createFromParcel(Parcel in) {
            return Department.valueOf(in.readString()); // crash
            //return new DeptEnum(in); // android studio generated code but has error: enum types may not be instantiated
        }

        @Override
        public Department[] newArray(int size) {
            return new Department[size];
        }
    };

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

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(name);
        parcel.writeInt(ordinal);
    }
}

Ошибка

Нет константы перечисления Department.Sales

Я получил помощь от этого ответа дляline return Department.valueOf(in.readString());


Наблюдение

Я полагаю, это связано с наличием как имени, так и порядкового значения, мой тип перечисления не такой простой, как всвязанный ответ, как-то мне нужно создать перечисление из посылки.

public Department createFromParcel(Parcel in) {
    Log.d("abc", "createFromParcel: " + in.readString()); // returns null
    Log.d("abc", "createFromParcel: " + in.readInt()); // returns 127 or 128
    return SHIPPING; // hard coded value works but of course not a solution
}

1 Ответ

1 голос
/ 25 октября 2019

Вам не нужно посылать порядковый номер. Выполнение значения valueOf только для имени будет правильным

Однако параметр valueOf должен совпадать с точно именем, определенным перечислением.

Например, это будет работать для продаж идоставка, но не HR

Department.valueOf(in.readString().toUpperCase());

Решение, которое вам нужно, - перебрать Department.values() и сравнить каждое поле имени значений с результатом in.readString ()

Как я могу найти перечисление Java по его строковому значению?

Или вместо этого вы можете использовать порядковый номер, например, так как вы дублируете порядковую информацию и вам нужно гарантировать, чтоперечисления имеют порядковые номера

 return Department.values()[in.readInt() - 1]
...